Codeforces Round #318(ABCD)
2015-08-31 19:32
375 查看
A
题意:
每次操作可以让第一个数字加1,第一个数字之后的数字减1,问你最少变换多少可以使得第一个数字大于后面所有数字。解析:
先保存下所有的数字,以及该数字出现的个数。直接用map,每次取得map中最大的数字让这个数字的个数减去1,再把a[0]加一,在把这个最大的数字减去1,存入map中,直至a[0]大于所有的数字,输出最少的操作次数。
mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; const int N = 1005; int a , n; map<int, int> mp; map<int, int>::iterator it; int main() { while(~scanf("%d", &n)) { mp.clear(); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); if(i > 0) mp[a[i]]++; } it = mp.end(); it--; int ans = 0, maxa = it->first; while(a[0] <= maxa) { a[0]++; ans++; mp[maxa]--; mp[maxa-1]++; if(mp[maxa] == 0) it--; maxa = it->first; } printf("%d\n", ans); } return 0; }
B
题意:
n个人,m个询问,然后接下来m行告诉你a与b是相互认识的,但是这个认识不能够相互传递,也就是说a认识b,b认识c,但是a并不认识c。然后问你是否能够在这n个人中选取3个人,使得它们认识其他人的总数最少,并且这三个人要相互认识(也就是a-b,b-c,c-a),如果不存在则输出-1
解析:
枚举两条边判断这两条边能否构成三角形。mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int N = 4005; struct Edge { int u[2]; } edge ; int n, m; int deg ; bool G ; int check(int x, int y) { int ret = INF; int a, b, c, d; for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) { a = edge[x].u[i]; b = edge[y].u[j]; c = edge[x].u[i^1]; d = edge[y].u[j^1]; if(a == b && G[c][d]) { ret = deg[a] + deg[c] + deg[d] - 6; return ret; } } } return ret; } int cal() { int ret = INF; for(int i = 0; i < m; i++) { for(int j = i+1; j < m; j++) { ret = min(ret, check(i, j)); } } return ret == INF ? -1 : ret; } int main() { int u, v; while(~scanf("%d%d", &n, &m)) { memset(deg, 0, sizeof(deg)); memset(G, 0, sizeof(G)); for(int i = 0; i < m; i++) { scanf("%d%d", &u, &v); if(v == u || G[u][v]) continue; G[u][v] = G[v][u] = true; deg[u]++, deg[v]++; edge[i] = (Edge){u, v}; } printf("%d\n", cal()); } return 0; }
C
题意:
现在有n个人,每个人都持有a[i]这个价值的牌,并且每个人可以每次无限次数的使自己的牌扩大2倍,扩大3倍,然后问你是否可能使得最终所有人的牌的价值数变成一样的。思路:
可以逆向思维,既然这些数字乘以无限多的2和3可以得到一样的数字,那么这些数字,不停的除以2与3,剩下的数字也可以通过不断的乘以2或者3得到。所以我们可以使所有的数都不停的除以2与3,直到不能除为止,然后判断除完以后所有的数是否相同,如果相同,则说明是可以的,否则,则是不可以的。
mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = (int)1e5 + 10; int a , n; bool judge() { for(int i = 1; i < n; i++) if(a[i] != a[i-1]) return false; return true; } int main() { while(~scanf("%d", &n)) { for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } for(int i = 0; i < n; i++) { while(a[i]%2==0) a[i]/=2; while(a[i]%3==0) a[i]/=3; } puts(judge() ? "Yes" : "No"); } return 0; }
D
题意:
有n个方格,然后每个方格都有一个高度,然后每次都可以把那些非完整块(就是它的四个方向没有被完全包围)给连在一起消去。问你最后把所有的方块消去需要几次。解析:
就是求最高的 1, 2, 3, 4 …, 4, 3, 2, 1这样的等腰三角形的高度。首先初始化为L[0]=0,R[n+1]=0L[0]=0,R[n+1]=0,我们设两个数组L代表的是从左边开始消去每次的最大高度,R则是右边的。
L[i]=min(h[i],L[i−1]+1)L[i]=min(h[i],L[i-1]+1)
R[i]=min(h[i],R[i+1]+1)R[i]=min(h[i],R[i+1]+1)
ans=max(ans,min(L[i],R[i]))ans = max(ans, min(L[i], R[i]))
mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5 + 10; int h , L , R ; int n; int main() { while(~scanf("%d", &n)) { for(int i = 1; i <= n; i++) { scanf("%d", &h[i]); } L[0] = R[n+1] = 0; for(int i = 1; i <= n; i++) { L[i] = min(L[i-1] + 1, h[i]); } for(int i = n; i >= 1; i--) { R[i] = min(R[i+1] + 1, h[i]); } int ans = 0; for(int i = 1; i <= n; i++) { ans = max(ans, min(L[i], R[i])); } printf("%d\n", ans); } return 0; }
相关文章推荐
- 04-树6. Huffman Codes--优先队列(堆)在哈夫曼树与哈夫曼编码上的应用
- 点击对应的a标签返回相应的第几个
- Android 色板
- easyui validatebox 去除校验 绑定校验
- HDU1019
- leetcode--Missing Number
- 2015年8月之 英雄不老
- JS+Html控制控件的显示与隐藏
- SpringMVC异常之The request sent by the client was syntactically incorrect解决方案
- 2015年8月之 英雄不老
- HIVE中关于collect_set与explode函数妙用
- CentOS 7 + Nginx 1.9.4
- .net 两个窗口传递信息
- 【项目】TreeView控件的CheckBox选中事件
- MTD应用学习:mtd和mtdblock的区别
- 前缀、中缀、后缀表达式
- jquery查找指定id元素下的某个或某些元素
- 二叉树的各种遍历,二叉树改链表,二叉树复习
- SwipeListView实现QQ消息侧滑删除功能
- 第六周第一天