弱鸡儿长乐爆零旅Day5
T1圆圈舞蹈
【问题描述】
熊大妈的奶牛在时针的带领下,围成了一个圈跳舞。由于没有严格的教育,奶牛们之间的间隔不一致。
奶牛想知道两只最远的奶牛到底隔了多远。奶牛A到B的距离为A顺时针走和逆时针走,到达B的较短路程。告诉你相邻个奶牛间的距离,请你告诉奶牛两只最远的奶牛到底隔了多远。
【输入格式】
第一行一个整数N,表示有N只奶牛。(2<=N<=100000)
接下来2~N+1行,第I行有一个数,表示第I-1头奶牛顺时针到第I头奶牛的距离。(1<=距离<=maxlongint,距离和<=maxlongint)
第N+1行的数表示第N头奶牛顺时针到第1头奶牛的距离。
【输出格式】
一行,表示最大距离。
【输入样例】Circle.in
5
1
2
3
4
5
【输出样例】Circle.out
7
【样例解析】
所有奶牛I到J之间的距离和到达方式(顺为顺时针,逆为逆时针)如下
I\J |
1 |
2 |
3 |
4 |
5 |
1 |
0 |
1(顺) |
3(顺) |
6(顺) |
5(逆) |
2 |
1(逆) |
0 |
2(顺) |
5(顺) |
6(逆) |
3 |
3(逆) |
2(逆) |
0 |
3(顺) |
7(顺) |
4 |
6(逆) |
5(逆) |
3(逆) |
0 |
4(顺) |
5 |
5(顺) |
6(顺) |
7(逆) |
4(逆) |
0 |
所以,最远的两头奶牛为3到5,距离是7。
(我也不是很懂为什么我写的n^2的算法过了qaq)
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int a[100010]; 5 int summ[100010]; 6 int ans=-1; 7 int mid,n; 8 inline int read() 9 { 10 int f=0; 11 char ch=getchar(); 12 while(ch>'9' || ch<'0') 13 ch=getchar(); 14 while(ch>='0' && ch<='9'){ 15 f=f*10+ch-'0'; 16 ch=getchar(); 17 } 18 return f; 19 } 20 21 int main() 22 { 23 freopen("circle.in","r",stdin); 24 freopen("circle.out","w",stdout); 25 scanf("%d",&n); 26 for(int i=1;i<=n;i++){ 27 a[i]=read(); 28 summ[i]=summ[i-1]+a[i]; 29 } 30 int mid=summ[n]/2; 31 for(int i=1;i<=n;i++){ 32 for(int j=i+1;j<=n;j++){ 33 ans=max(ans,min(summ[j]-summ[i],summ[n]-summ[j]+summ[i])); 34 if(ans==mid)break; 35 } 36 } 37 printf("%d",ans); 38 return 0; 39 }
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN = 100005; 8 int ans, a[MAXN], b[MAXN], n, i, j, k, tot, t; 9 int main() 10 { 11 freopen("circle.in", "r", stdin); 12 freopen("circle.out", "w", stdout); 13 cin >> n; 14 for(i = 1; i <= n; i ++) 15 scanf("%d", &a[i]); 16 for(i = 1; i <= n; i ++) 17 tot += a[i]; 18 j = 2; 19 t = a[1]; 20 for(i = 1; i <= n; i ++) 21 { 22 while (min(t, tot - t) <= min(t + a[j], tot - t - a[j]) && j < n) j ++, t += a[j - 1]; 23 ans = max(ans, min(t, tot - t)); 24 t -= a[i]; 25 } 26 cout << ans << endl; 27 fclose(stdin); fclose(stdout); 28 }
标程如上 是O(n)算法
因为最远距离一定是接近mid值的 因此我们可以寻找不超过mid的最大值
T2小麦亩产一千八
【问题描述】
“有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾……”,话说HYSBZ(Hengyang School for Boys & Zy)学识渊博孩纸们一讲到粮食,都会想起印度那个著名的故事:国王要在第一个格子里放入一粒小麦,接下来的格子放入前面一个格子的两倍的小麦。这样所需小麦总数是巨大的,哪是不用金坷垃就能完成的任务?不过为了减轻国王的任务,那个下棋获胜的宰相换了一个要求:“我只需要你在棋盘外放一粒小麦,可以将其理解为第0个格子,然后你需要在第一个格子里放入若干小麦,之后每一个格子放入前两个格子的小麦数之和的小麦,并且要满足第a个格子放x粒小麦,第b个格子放……”说到这,宰相突然发现自己说的满足第a个格子放x粒小麦的情况可能不存在……欺君可是大罪啊!国王看到宰相迟迟不说,自己也烦了!我自己来算!于是国王拜托你,让你算出第b个格子应该放几粒小麦。当然,就算答案不存在,你也是要告诉国王的。
【输入格式】kela.in
该题有多组数据,请读到文件末结束。
对于每一组数据仅一行,3个正整数a,x,b,分别表示第a个格子放了x粒小麦,以及你所需要计算的是第b个格子的小麦数量。
【输出格式】kela.out
对于每一次询问,仅1个整数,为第b个格子的小麦数量,若宰相说的情况不存在,那么请输出-1。
样例输入 |
样例输出 |
1 1 2 3 5 4 3 4 6 12 17801 19 |
2 8 -1 516847 |
【样例解释】
对于样例二,f[1]=2时,能够满足f[3]=5,因此宰相没有撒谎,此时第5个格子的小麦数应为f[4]=f[2]+f[3]=3+5=8.
【数据范围与约定】
对于50%的数据:如果答案存在,那么p<=50
对于100%的数据:1<=数据组数<=10000,1<=a,b<=20, 数据保证如果答案存在,那么1<=p<=1000000.(注:p是第一格放置的小麦数)。
只是第一个放的小麦数在int范围里 后面的未必
所以 要开longlongTvT
全部加longlong就ac了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define ass cout<<"ass" 5 using namespace std; 6 //qaq是第二位上的数 7 //第n位上的数是fb[n-1]*qaq+fb[n-2] 8 long long qaq; 9 long long x,a,b; 10 long long fb[30]={0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393}; 11 int main() 12 { 13 14 while(scanf("%lld%lld%lld",&a,&x,&b)!=EOF) 15 { 16 if((x-fb[a-1])%fb[a]){ 17 printf("-1\n"); 18 continue; 19 } 20 qaq=(x-fb[a-1])/fb[a]; 21 printf("%lld\n",fb[b]*qaq+fb[b-1]); 22 } 23 return 0; 24 }
T2好元素
【问题描述】
小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况:
Am+An+Ap = Ai (1 <= m, n, p < i <= N , m,n,p可以相同),那么Ai就是一个好元素。
现在小A有一个数列,请你计算数列中好元素的数目。
【输入格式】
第一行只有一个正整数N,意义如上。
第二行包含N个整数,表示数列{An}。
【输出格式】
输出一个整数,表示这个数列中好元素的个数。
【输入样例】
Sample1 |
2 1 3 |
Sample2 |
6 1 2 3 5 7 10 |
Sample3 |
3 -1 2 0 |
【输出样例】
Sample1 |
1 |
Sample2 |
4 |
Sample3 |
1 |
【数据范围】
对于10%的数据1<=N<=10
对于40%的数据1<=N<=500 -10^5<=Ai<=10^5
对于70%的数据1<=N<=5000 -10^6<=Ai<=10^6
对于100%的数据1<=N<=5000 -10^9<=Ai<=10^9
哈希表
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int qaq=1e8+5; 6 const int mod=4194303; 7 int a[5010]; 8 int ans; 9 inline int read() 10 { 11 int f=0; 12 int temp=1; 13 char ch=getchar(); 14 while(ch>'9' || ch<'0'){ 15 if(ch=='-')temp=-1;ch=getchar(); 16 } 17 while(ch>='0' && ch<='9'){ 18 f=f*10+ch-'0'; 19 ch=getchar(); 20 } 21 return temp*f; 22 } 23 int head[mod+10],ver[qaq],nxt[qaq],tot; 24 void add(int x){ 25 int y=x&mod;//负数别% 26 ver[++tot]=x; 27 nxt[tot]=head[y]; 28 head[y]=tot; 29 } 30 bool query(int x){ 31 int y=x&mod; 32 for(int i=head[y];i;i=nxt[i]){ 33 if(x==ver[i])return true; 34 } 35 return false; 36 } 37 int main(){ 38 int n; 39 scanf("%d",&n); 40 for(int i=1;i<=n;i++) 41 a[i]=read(); 42 43 44 for(int i=1;i<=n;i++){ 45 for(int j=1;j<i;j++) 46 if(query(a[i]-a[j])){ 47 ans++; 48 break; 49 } 50 for(int k=1;k<=i;k++){ 51 add(a[i]+a[k]); 52 } 53 } 54 printf("%d",ans); 55 return 0; 56 }