数学
题意:选n个正整数,使得和能够整除K,并且这n个整数中的最大数尽可能的小。最大尽可能小,所以要求最小和,再让最小和给n个数均摊,找到其中最大的值。
当n<=k, 最小和就是K,n个数中的最大的数就是k/n向上取整,
向上取整方法:(n+k-1)/k;
当n>k,最小和就是n/k向上取整再*K,然后n个数的最大数就是最小和向除n上取整
其实不管n和K的关系最小和就是n/k向上取整再*K
AC代码
#include <iostream>
using namespace std;
int main(){
long long n,k,sum,ans;
int T;
cin >> T;
for(int i = 0;i < T;i++){
cin >> n >> k;
sum =(n + k -1)/k * k;
ans = (sum + n -1)/n;
cout << ans << endl;
}
//system("pause");
return 0;
}
思维
题意: 给你n个数字,n个数字和k,第一个数字是商品起始价格,之后是每个月涨了多少。>要求每个人月涨价前/涨价后 <= k/100.
涨价前/涨价后 <= k/100. 涨价前100 <= k涨价后 能用乘法就不要用除法。避免精度丢失问题。
每个月都要满足上式,所以如果不满足,只能上调价格!!!,求最少总共了改变多少价格。所以一旦不满足上式,你只要上调涨价前的价格直到刚好满足上式就好,不许要像下面的Note那样,(感觉就是在误导)
Note
In the first test case, you can, for example, increase p0 by 50 and p1 by 49 and get array [20150,50,202,202]. Then you get the next inflation coefficients:
AC代码
#include <iostream>
using namespace std;
int main(){
int T,n;
int k;
cin >>T;
long long sum,x,ans,sum1;
for(int t = 0;t < T;t++){
cin >> n >> k;
ans = 0;
cin >> sum;
for(int i = 1;i < n;i++){
cin >> x;
if(x*100 > sum *k){
//cout << x << " x" << endl;
sum1 = (100*x + k -1)/k;
ans+=(sum1-sum);
sum = sum1;
}
sum +=x;
}
cout << ans << endl;
}
//system("pause");
return 0;
}
贪心
题意:让你从n个连接的链条中找长度最长的简单环(绕环一圈只过每个点一次)因此 ai > bi也满足,也就是有边交叉也是满足的,所以每次加上ai——bi的长度是abs(ai-bi),但ai == bi时,i 和i -2个链条就不能相连了
贪心,对于第i条,如果能和第i-2条相连(ai!=bi)那么就判断连和不连哪个长,然后选择长的个保存为 当前对于下个链条有作用的最大环,对于第i条链子.画图不难发现如果第i-2条不连(不经过i-2上面的点)更大,那么第i-2条对之后也没有帮助,所以可以放心丢弃,也就是无后效性所以可以贪心。然后再和已有的最大值比较就行。
AC代码
#include <iostream>
#include <stdlib.h>
using namespace std;
int num[100200];
int a[100020];
int b[100020];
long long max(long long a,long long b){
return a > b?a:b;
}
int main(){
int T;
int n;
long long ans,sum,x,x1;
cin >> T;
for(int t = 0;t < T;t++){
scanf("%d",&n);
ans = 0;
sum = 0;
for(int i = 0;i < n;i++)
scanf("%d", &num[i]);
for(int i = 0;i < n;i++)
scanf("%d",&a[i]);
for(int i = 0;i < n;i++)
scanf("%d",&b[i]);
ans = 0;
for(int i = 1;i < n;i++){
if(a[i] == b[i])
sum = 0;//前面的连不起来 如果sum是max就已经被收了就没有意义了
x = num[i]+1 + abs(a[i]-b[i]);//只取第i个
x1 = sum;//在前面的基础上取第i个
if(x1)
x1-=abs(a[i]-b[i]);
x1+=(1+num[i]);
sum = max(x,x1);//取了第i个的最大环 如果只取i 比取i和之前相连,就说明i之前的没有意义,
//可以扔了
ans = max(ans,sum);
}
printf("%lld\n",ans);
}
//system("pause");
return 0;
}