A - Choosing Capital for Treeland
CodeForces - 219D
题意:有一颗单向边的树,要选取一个结点作为首都。要求是这个结点到其它结点,总共需要翻转的路径数量最少(因为是单向边,翻转了才能到达另一个结点)。
做法:树形dp。
代码:待补。
B - Maximal Intersection
CodeForces - 1029C
题意:给出n个区间,然后你可以删除一个区间,问你剩下的区间的交集的最大长度是多少。
思路:首先我们得先知道n条线段公共的线段一定是(LMAX,RMIN) ,那我们可以先排序,然后枚举删除边。
代码:
1 /* 2 I have a dream!A AC deram!! 3 orz orz orz orz orz orz orz orz orz orz orz 4 orz orz orz orz orz orz orz orz orz orz orz 5 orz orz orz orz orz orz orz orz orz orz orz 6 7 */ 8 9 #include<iostream> 10 #include<cstdio> 11 #include<cstdlib> 12 #include<cstring> 13 #include<cmath> 14 #include<string> 15 #include<algorithm> 16 #include<vector> 17 #include<queue> 18 #include<set> 19 #include<stack> 20 using namespace std; 21 typedef long long ll; 22 const int maxn = 1e4 + 5; 23 const int N = 2100; 24 #define pa pair<int,int> 25 inline int read() 26 { 27 int x = 0, f = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -1; 28 for (; isdigit(ch); ch = getchar())x = x * 10 + ch - '0'; return x * f; 29 } 30 int l[300005],r[300005]; 31 int main() 32 { 33 multiset<int>a,b; 34 int n; 35 scanf("%d",&n); 36 for(int i=1;i<=n;i++) 37 { 38 scanf("%d%d",&l[i],&r[i]); 39 a.insert(l[i]); 40 b.insert(r[i]); 41 } 42 int ans=0; 43 for(int i=1;i<=n;i++) 44 { 45 a.erase(a.find(l[i])); 46 b.erase(b.find(r[i])); 47 ans=max(ans,*b.begin()-*a.rbegin()); 48 a.insert(l[i]); 49 b.insert(r[i]); 50 } 51 printf("%d\n",ans); 52 return 0; 53 }
C - Tempter of the Bone
HDU - 1010
题意:一只小狗被骨头诱惑来到一个宫殿。但是每走一步后面的石头就会掉落,问是否能在T时刻内恰好到达D。
思路:DFS+剪枝。
代码:待补。
D - Pocket Cube
HDU - 5983
题意:给你一个2*2*2的魔方的图,问你是否能在1步以内还原,实现每面都相同。
思路:这个很考验几何思维,想不好就被题目的图给误解了。你拿一个立方体的物体出来就可以观察到翻转方案有六种。然后模拟暴力。
代码:
/* I have a dream!A AC deram!! orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz orz */ #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<vector> #include<queue> #include<set> #include<stack> using namespace std; typedef long long ll; const int maxn = 1e4 + 5; const int N = 2100; #define pa pair<int,int> inline int read() { int x = 0, f = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -1; for (; isdigit(ch); ch = getchar())x = x * 10 + ch - '0'; return x * f; } int map[20][20],mapp[20][20]; bool same(int a, int b, int c, int d) { if (a == b && b == c && c == d) return true; else return false; } int main() { int T = read(); while (T--) { int flag = 0; int a[8][5]; int b[25]; int i, j; for (int i = 1; i <= 6; i++) { for (j = 1, b[i] = 1; j <= 4; j++) { scanf("%d", &a[i][j]); if (j >= 2) { if (a[i][j] != a[i][j - 1]) b[i] = 0; } } } if (same(a[1][1], a[1][2], a[1][3], a[1][4]) && same(a[2][1], a[2][2], a[2][3], a[2][4]) && same(a[3][1], a[3][2], a[3][3], a[3][4]) && same(a[4][1], a[4][2], a[4][3], a[4][4]) && same(a[5][1], a[5][2], a[5][3], a[5][4]) && same(a[5][1], a[5][2], a[5][3], a[5][4])) flag = 1; if (b[1] && b[3] && same(a[2][1], a[2][2], a[5][1], a[5][3]) && same(a[6][1], a[6][3], a[2][3], a[2][4]) && same(a[5][2], a[5][4], a[4][1], a[4][2]) && same(a[4][3], a[4][4], a[6][4], a[6][2])) flag = 1; if (b[1] && b[3] && same(a[4][1], a[4][2], a[6][1], a[6][3]) && same(a[4][3], a[4][4], a[5][1], a[5][3]) && same(a[5][2], a[5][4], a[2][3], a[2][4]) && same(a[2][1], a[2][2], a[6][4], a[6][2])) flag = 1; if (b[5] && b[6] && same(a[1][2], a[1][4], a[2][1], a[2][3]) && same(a[2][2], a[2][4], a[3][1], a[3][3]) && same(a[3][2], a[3][4], a[4][3], a[4][1]) && same(a[4][4], a[4][2], a[1][3], a[1][1])) flag = 1; if (b[5] && b[6] && same(a[2][2], a[2][4], a[1][1], a[1][3]) && same(a[1][2], a[1][4], a[4][3], a[4][1]) && same(a[4][4], a[4][2], a[3][1], a[3][3]) && same(a[3][2], a[3][4], a[2][1], a[2][3])) flag = 1; if (b[2] && b[4] && same(a[1][1], a[1][2], a[6][3], a[6][4]) && same(a[6][1], a[6][2], a[3][1], a[3][2]) && same(a[3][3], a[3][4], a[5][3], a[5][4]) && same(a[5][1], a[5][2], a[1][3], a[1][4])) flag = 1; if (b[2] && b[4] && same(a[1][1], a[1][2], a[5][3], a[5][4]) && same(a[5][1], a[5][2], a[3][1], a[3][2]) && same(a[3][3], a[3][4], a[6][3], a[6][4]) && same(a[6][1], a[6][2], a[1][3], a[1][4])) flag = 1; if (flag) printf("YES\n"); else printf("NO\n"); } return 0; }
E - Reward
HDU - 2647
题意:一个人要给工人们发工资,每个人的起始工资为888.如果有一个人觉得自己比另外一个人高的话,就给他+1元(答案要求总工资最少),问最后发的钱最少为多少。如果出现了环或不能满足的情况,输出-1。
思路:就是拓扑排序。最关键的一步:add[map[u][i]] = max(add[u] + 1, add[map[u][i]])。
代码:
1 /* 2 I have a dream!A AC deram!! 3 orz orz orz orz orz orz orz orz orz orz orz 4 orz orz orz orz orz orz orz orz orz orz orz 5 orz orz orz orz orz orz orz orz orz orz orz 6 7 */ 8 9 #include<iostream> 10 #include<cstdio> 11 #include<cstdlib> 12 #include<cstring> 13 #include<cmath> 14 #include<string> 15 #include<algorithm> 16 #include<vector> 17 #include<queue> 18 #include<set> 19 #include<stack> 20 using namespace std; 21 typedef long long ll; 22 const int maxn = 1e4 + 5; 23 const int N = 2100; 24 #define pa pair<int,int> 25 inline int read() 26 { 27 int x = 0, f = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -1; 28 for (; isdigit(ch); ch = getchar())x = x * 10 + ch - '0'; return x * f; 29 } 30 int in[maxn], add[maxn]; 31 vector<int>map[maxn]; 32 33 ll top_sort(int n) 34 { 35 queue<int>q; 36 int cnt = 0; 37 while (!q.empty()) 38 q.pop(); 39 for (int i = 1; i <= n; i++) 40 if (in[i] == 0) 41 q.push(i); 42 int u; 43 while (!q.empty()) 44 { 45 u = q.front(); 46 q.pop(); 47 cnt++; 48 for (int i = 0; i < map[u].size(); i++) 49 { 50 in[map[u][i]]--; 51 if (in[map[u][i]] == 0) 52 { 53 q.push(map[u][i]); 54 add[map[u][i]] = max(add[u] + 1, add[map[u][i]]); 55 } 56 } 57 } 58 if (cnt != n) 59 return -1; 60 ll ans=0; 61 for (int i = 1; i <= n; i++) 62 ans += add[i] + 888; 63 return ans; 64 } 65 66 int main() 67 { 68 int n, m; 69 while (~scanf("%d %d", &n, &m)) 70 { 71 memset(in, 0, sizeof(in)); 72 memset(add, 0, sizeof(add)); 73 memset(map, 0, sizeof(map)); 74 for (int i = 0; i < m; i++) 75 { 76 int a = read(), b = read(); 77 map[b].push_back(a); 78 in[a]++; 79 } 80 printf("%lld\n", top_sort(n)); 81 } 82 }
F - Rikka with Mutex
HDU - 6261
题意:给你一个只包含V和P的字符串,要求通过这一条字符串。V可以获得能量,P会消耗能量,能量是公共的,可以多个人去,获得多个能量,最后让一个人通过这条字符串即可。
思路:二分+贪心或者简单的贪心。
代码:待补。