HDU
来源:互联网 发布:淘宝怎样绑定手机号 编辑:程序博客网 时间:2024/06/09 14:21
A Simple Stone Game
Problem Description
After he has learned how to play Nim game, Bob begins to try another stone game which seems much easier.
The game goes like this: one player starts the game withN piles of stones. There is ai stones on the i th pile. On one turn, the player can move exactly one stone from one pile to another pile. After one turn, if there exits a number x(x>1) such that for each pile bi is the multiple of x where bi is the number of stone of the this pile now), the game will stop. Now you need to help Bob to calculate the minimum turns he need to stop this boring game. You can regard that 0 is the multiple of any positive number.
The game goes like this: one player starts the game with
Input
The first line is the number of test cases. For each test case, the first line contains one positive number N(1≤N≤100000) , indicating the number of piles of stones.
The second line containsN positive number, the i th number ai(1≤ai≤100000) indicating the number of stones of the i th pile.
The sum ofN of all test cases is not exceed 5∗105 .
The second line contains
The sum of
Output
For each test case, output a integer donating the answer as described above. If there exist a satisfied number x initially, you just need to output 0 . It's guaranteed that there exists at least one solution.
Sample Input
251 2 3 4 525 7
Sample Output
21
题意:给你几堆石子,问你最少要移动多少个石子才能使得所有堆的大小的最大公约数>1
解题思路:最容易想到的,就是枚举所有的可能,但是和有10^10这么大。类似判断一个数是否是素数的思想。我们不用枚举全部,只需枚举到 sqrt(sum)即可。但是这样还是会超时。再想想,只需要枚举sum的所有质因数即可。枚举之后,就是计算最少要多少步了,这里很容易想,贪心的填满最大的余数即可。具体看代码。
#include<iostream>#include<deque>#include<memory.h>#include<stdio.h>#include<map>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<stack>#include<queue>#include<set>using namespace std;typedef long long int ll;//素数打表#define M 1000005bool visit[1010000];int prime[1000000];void table(){ memset(visit,true,sizeof(visit)); int num = 0; for (int i = 2; i <= M; ++i){ if (visit[i] == true){ num++; prime[num] = i; } for (int j = 1; ((j <= num) && (i * prime[j] <= M)); ++j){ visit[i * prime[j]] = false; if (i % prime[j] == 0) break; } }}int a[100005];int b[100005];int main(){ int t; scanf("%d",&t); table() ; while(t--){ int n; scanf("%d",&n); ll sum=0; int maxx=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum+=a[i]; maxx=max(maxx,a[i]); } ll ans=sum-maxx;//最大值 //枚举每一个素数 for(int p=1;p<=M;p++){ if(prime[p]==0) break; //如果不是因子,跳过 if(sum%prime[p]) continue; //求余 for(int i=1;i<=n;i++){ b[i]=a[i]%prime[p]; } //排序 sort(b+1,b+n+1); ll ta=0;//统计答案 int l=1,r=n; //看平均分完要多少次 while(l<r){ int temp=prime[p]-b[r]; if(b[l]>temp){ b[l]-=temp; ta+=temp; r--; } else{ b[r]+=b[l]; ta+=b[l]; l++; } } ans=min(ans,ta);//取最小 } printf("%lld\n",ans); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 【java】求1-10的和。
- 【Angular2】AnswerSheet组件设计
- 14 个你可能不知道的 JavaScript 调试技巧
- 侧滑菜单xml和代码
- ROI Pooling层详解
- HDU
- 链表相关练习题
- 简单实现断点续传+MVP+Retrofit+RxJava
- 简单的断点传送,不需理解,粘贴运行
- 通国轮廓进行抠图 掩膜
- F1
- ECS访问RDS超时504的解决方法
- Android Studio常见问题 -- AndroidManifest.xml 替换别名问题
- Python CSV模块简介