2016年中国大学生程序设计竞赛(杭州)
2016-10-30 21:46
495 查看
hdu ArcSoft’s Office Rearrangement
这道题做了好久未果,我感觉好难,为啥好多人都做出来了,自己就很气,发现自己发现合并只能与相邻的砖块合并,好气呀!!赛后补题用了2种方法去做它用于解气。第一种方法纯模拟,如果当前值大于平均值直接分裂,多余的部分给右边,因为是从左往右进行的。注意用long long,不然估计又要哭一天!!!
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5+10; #define LL long long LL a[maxn]; int main(){ LL T, N, K; scanf("%I64d", &T); for(int kase = 1; kase <= T; kase++){ scanf("%I64d%I64d", &N, &K); LL sum = 0; for(int i = 0; i < N; i++){ scanf("%I64d", &a[i]); sum += a[i]; } printf("Case #%d: ", kase); if(sum%K) printf("-1\n"); else{ LL ans = 0; sum /= K; for(int i = 0; i < N; i++){ if(a[i] > sum){ if(a[i]%sum){ ans += (a[i]/sum)+1; a[i+1] += a[i]%sum; } else ans += (a[i]/sum)-1; } else if(a[i] < sum){ a[i+1] += a[i]; ans++; } } printf("%I64d\n", ans); } } return 0; }
另一种方法就是求前缀和的思想,如果成立那么我们就可以减少合并或者分裂的次数,给出代码。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5+10; #define LL long long LL a[maxn]; int main(){ LL T, N, K; scanf("%I64d", &T); for(int kase = 1; kase <= T; kase++){ scanf("%I64d%I64d", &N, &K); LL sum = 0; for(int i = 0; i < N; i++){ scanf("%I64d", &a[i]); sum += a[i]; } printf("Case #%d: ", kase); if(sum%K) printf("-1\n"); else{ LL ans = 0; sum /= K; for(int i = 0; i < N; i++){ if(a[i] > sum){ if(a[i]%sum){ ans += (a[i]/sum)+1; a[i+1] += a[i]%sum; } else ans += (a[i]/sum)-1; } else if(a[i] < sum){ a[i+1] += a[i]; ans++; } } printf("%I64d\n", ans); } } return 0; }
hdu 5934 Bomb
强连通分量的题目,先缩点,然后处理,对于每一个缩点求出入度,然后入度为0的地方一定要引爆,如果入度为0的地方是一个有多个顶点的强连通分量则求最小值,注意用long long,不然算距离的时候会爆炸,又要在厕所哭一年!!!#include <cmath> #include <cstdio> #include <vector> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1005; #define LL long long struct Node{ LL x, y, r, c; }node[maxn]; int n; vector <int> G[maxn]; vector <int> rG[maxn]; vector <int> vs; bool used[maxn]; int cmp[maxn], degree[maxn], vis[maxn][maxn]; void addedge(int from, int to){ G[from].push_back(to); rG[to].push_back(from); } void dfs(int v){ //正向建边给所有节点设置一个标号 used[v] = true; for(int i = 0; i < G[v].size(); i++) if(!used[G[v][i]]) dfs(G[v][i]); vs.push_back(v); } void rdfs(int v, int k){ used[v] = true; cmp[v] = k; for(int i = 0; i < rG[v].size(); i++) if(!used[rG[v][i]]) rdfs(rG[v][i], k); } int scc(){ memset(used, 0, sizeof(used)); vs.clear(); for(int v = 0; v < n; v++) // 给所有节点进行编号 if(!used[v]) dfs(v); memset(used, 0, sizeof(used)); int k = 0; for(int i = vs.size()-1; i >= 0; i--) //通过反向边来跑找到强连通分量 if(!used[vs[i]]) rdfs(vs[i], k++); return k; //k表示有多少强连通分量 } void init(){ memset(degree, 0, sizeof(degree)); memset(vis, 0, sizeof(vis)); for(int i = 0; i < maxn; i++) G[i].clear(), rG[i].clear(); } int main(){ int T; scanf("%d", &T); for(int kase = 1; kase <= T; kase++){ init(); scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%I64d%I64d%I64d%I64d", &node[i].x, &node[i].y, &node[i].r, &node[i].c); for(int i = 0; i < n; i++){ for(int j = i+1; j < n; j++){ double dis = sqrt((LL)(node[i].x-node[j].x)*(node[i].x-node[j].x)+(LL)(node[i].y-node[j].y)*(node[i].y-node[j].y)); if(node[i].r >= dis) addedge(i, j), vis[i][j] = 1; if(node[j].r >= dis) addedge(j, i), vis[j][i] = 1; } } int k = scc(); for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ if(!vis[i][j] || cmp[i] == cmp[j]) continue; degree[cmp[j]]++; } } int ans = 0; for(int i = 0; i < k; i++){ if(degree[i] == 0){ int temp = 1e5; for(int j = 0; j < n; j++) if(cmp[j] == i) if(node[j].c < temp) temp = node[j].c; ans += temp; } } printf("Case #%d: %d\n", kase, ans); } return 0; }
hdu 5935 Car
从最后一个点向前处理,然后二分时间找速度,错了一下午!因为我用了单调队列去处理,结果死的比谁都惨!!#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5+100; int a[maxn]; int main(){ #ifdef LOCAL_BUG freopen("input.txt", "r", stdin); #endif // LOCAL_BUG int T, n; scanf("%d", &T); for(int kase = 1; kase <= T; kase++){ scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); a[0] = 0; for(int i = 0; i < n; i++) a[i] = a[i+1] - a[i]; double temp = a[n-1]; int ans = 1; for(int i = n-2; i >= 0; i--){ double x = a[i]; int l = 1, r = 1e9; while(l < r){ int mid = (l+r)/2; if(x/mid <= temp) r = mid; else l = mid+1; } ans += r; temp = x/r; } printf("Case #%d: %d\n", kase, ans); } }
相关文章推荐
- HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))
- HDU 5937 Equation 【DFS+剪枝】 (2016年中国大学生程序设计竞赛(杭州))
- 2016年中国大学生程序设计竞赛(杭州)解题报告
- HDU5938+贪心+(2016年中国大学生程序设计竞赛(杭州))
- 2016年中国大学生程序设计竞赛(杭州)-重现赛
- HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))
- HDU 5937 Equation 【DFS+剪枝】 (2016年中国大学生程序设计竞赛(杭州))
- (2016年中国大学生程序设计竞赛(杭州)) HDU 5938 Four Operations 思维题 + 枚举
- HDU 5933 ArcSoft's Office Rearrangement 【模拟】(2016年中国大学生程序设计竞赛(杭州))
- (2016年中国大学生程序设计竞赛(杭州)-重现赛) Car 二分 (解决精度问题)
- (2016年中国大学生程序设计竞赛(杭州) )HDU 5943 Kingdom of Obsession 素数间距 + 匈牙利算法
- HDU 5933 ArcSoft's Office Rearrangement 【模拟】(2016年中国大学生程序设计竞赛(杭州))
- HDU 5938 Four Operations(贪心+细节)——2016年中国大学生程序设计竞赛(杭州)
- HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))
- 2016年中国大学生程序设计竞赛(杭州)-重现赛【01,02,03,06】
- 2016年中国大学生程序设计竞赛(杭州) 部分题解
- HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))
- 2016年中国大学生程序设计竞赛(杭州)-重现赛
- HDU 5935 Car 【模拟】 (2016年中国大学生程序设计竞赛(杭州))
- 2016年中国大学生程序设计竞赛(杭州) A ArcSoft's Office Rearrangement(贪心)