A. Greed
Jafar has n cans of cola. Each can is described by two integers: remaining volume of cola ai and can's capacity bi (ai ≤ bi).
Jafar has decided to pour all remaining cola into just 2 cans, determine if he can do this or not!
The first line of the input contains one integer n (2 ≤ n ≤ 100 000) — number of cola cans.
The second line contains n space-separated integers a1, a2, ..., an (0 ≤ ai ≤ 109) — volume of remaining cola in cans.
The third line contains n space-separated integers that b1, b2, ..., bn (ai ≤ bi ≤ 109) — capacities of the cans.
Print "YES" (without quotes) if it is possible to pour all remaining cola in 2 cans. Otherwise print "NO" (without quotes).
You can print each letter in any case (upper or lower).
2
3 5
3 6
YES
3
6 8 9
6 10 12
NO
5
0 0 5 0 0
1 1 8 10 5
YES
4
4 1 0 3
5 2 2 3
YES
题解:
水题直接判断最大次大容器能不能装所有的cola
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 int n; 8 long long x,sum,fir,sec; 9 int main() 10 { 11 scanf("%d",&n); 12 for(int i=1;i<=n;i++) 13 { 14 scanf("%lld",&x); 15 sum+=x; 16 } 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%lld",&x); 20 if(x>fir) 21 { 22 sec=fir; 23 fir=x; 24 } 25 else 26 { 27 if(x>sec) 28 sec=x; 29 } 30 } 31 if(sum<=fir+sec) puts("YES\n"); 32 else puts("NO\n"); 33 return 0; 34 }
B. Wrath
Hands that shed innocent blood!
There are n guilty people in a line, the i-th of them holds a claw with length Li. The bell rings and every person kills some of people in front of him. All people kill others at the same time. Namely, the i-th person kills the j-th person if and only if j < i and j ≥ i - Li.
You are given lengths of the claws. You need to find the total number of alive people after the bell rings.
The first line contains one integer n (1 ≤ n ≤ 106) — the number of guilty people.
Second line contains n space-separated integers L1, L2, ..., Ln (0 ≤ Li ≤ 109), where Li is the length of the i-th person's claw.
Print one integer — the total number of alive people after the bell rings.
4
0 1 0 10
1
2
0 0
2
10
1 1 3 0 0 0 2 1 0 3
3
题解:
看完题就上线段树,O(nlogn)能过就对了,D7C大佬写了指针扫描(没听说过)。
第一题提交数组开小(我已经开4倍了啊),re在第9个点
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 struct node 7 { 8 int l,r,sum,tag; 9 } tr[6000005]; 10 inline void build(int rt,int l,int r) 11 { 12 tr[rt].l=l,tr[rt].r=r; 13 if(l==r) return; 14 int mid=(l+r)>>1; 15 build(rt<<1,l,mid); 16 build(rt<<1|1,mid+1,r); 17 } 18 inline void pushdown(int rt,int l,int r) 19 { 20 int len=r-l+1; 21 if(tr[rt].tag) 22 { 23 tr[rt<<1].tag=tr[rt<<1|1].tag=1; 24 tr[rt].tag=0; 25 tr[rt<<1].sum=len-(len>>1); 26 tr[rt<<1|1].sum=len>>1; 27 } 28 } 29 inline void update(int rt,int L,int R) 30 { 31 int l=tr[rt].l,r=tr[rt].r; 32 if(L<=l && r<=R) 33 { 34 tr[rt].sum=r-l+1; 35 tr[rt].tag=1; 36 return; 37 } 38 pushdown(rt,l,r); 39 int mid=(l+r)>>1; 40 if(L<=mid) update(rt<<1,L,R); 41 if(R>mid) update(rt<<1|1,L,R); 42 tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum; 43 } 44 int main() 45 { 46 int n,x; 47 scanf("%d",&n); 48 build(1,1,n); 49 for(int i=1;i<=n;i++) 50 { 51 scanf("%d",&x); 52 update(1,max(1,i-x),i-1); 53 } 54 printf("%d",n-tr[1].sum); 55 }
C. Pride
You have an array a with length n, you can perform operations. Each operation is like this: choose two adjacent elements from a, say x and y, and replace one of them with gcd(x, y), where gcd denotes the greatest common divisor.
What is the minimum number of operations you need to make all of the elements equal to 1?
The first line of the input contains one integer n (1 ≤ n ≤ 2000) — the number of elements in the array.
The second line contains n space separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the elements of the array.
Print -1, if it is impossible to turn all numbers to 1. Otherwise, print the minimum number of operations needed to make all numbers equal to 1.
5
2 2 3 4 6
5
4
2 4 6 8
-1
3
2 6 9
4
题解:
贪心。只要出现一个1,每次把这个1与旁边的合并只要n-1次,明显最优。如果出现不了1,即无解。如何算出最少合并出现1,n^2暴力求最短区间gcd值为1即可。
然后过了,然后被hack。突然想到多个1的话,答案为n-1的数量。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 int f[2005][2005],a[2005],mnlen=1e9+7; 7 inline int gcd(int x,int y) 8 { 9 return !y?x:gcd(y,x%y); 10 } 11 int main() 12 { 13 int n,cnt=0; 14 scanf("%d",&n); 15 for(int i=1;i<=n;i++) 16 { 17 scanf("%d",&a[i]); 18 if(a[i]==1) cnt++; 19 f[i][i]=a[i]; 20 } 21 if(cnt!=0) 22 { 23 printf("%d\n",n-cnt); 24 return 0; 25 } 26 for(int i=1;i<=n;i++) 27 { 28 int num=a[i]; 29 for(int j=i+1;j<=n;j++) 30 { 31 num=gcd(num,a[j]); 32 f[i][j]=num; 33 if(num==1) 34 { 35 mnlen=min(mnlen,j-i+1); 36 break; 37 } 38 } 39 } 40 if(mnlen==1e9+7) puts("-1\n"); 41 else printf("%d",mnlen+n-2); 42 return 0; 43 }
D. Gluttony
You are given an array a with n distinct integers. Construct an array b by permuting a such that for every non-empty subset of indices S = {x1, x2, ..., xk} (1 ≤ xi ≤ n, 0 < k < n) the sums of elements on that positions in a and b are different, i. e.

The first line contains one integer n (1 ≤ n ≤ 22) — the size of the array.
The second line contains n space-separated distinct integers a1, a2, ..., an (0 ≤ ai ≤ 109) — the elements of the array.
If there is no such array b, print -1.
Otherwise in the only line print n space-separated integers b1, b2, ..., bn. Note that b must be a permutation of a.
If there are multiple answers, print any of them.
2
1 2
2 1
4
1000 100 10 1
100 1 1000 10
题解:
构造题。实话说结论很简单,就是每个数变成下一个比他大的数,最大的数变成最小的即可。1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cstdio> 5 #include<algorithm> 6 using namespace std; 7 struct node 8 { 9 int v,pos; 10 } a[10005]; 11 inline bool cmp(node X,node Y) 12 { 13 return X.v<Y.v; 14 } 15 inline bool cp(node X,node Y) 16 { 17 return X.pos<Y.pos; 18 } 19 int main() 20 { 21 int n; 22 scanf("%d",&n); 23 for(int i=1;i<=n;i++) 24 { 25 scanf("%d",&a[i].v); 26 a[i].pos=i; 27 } 28 sort(a+1,a+n+1,cmp); 29 int t=a[1].v; 30 for(int i=1;i<=n;i++) 31 a[i].v=a[i+1].v; 32 a[n].v=t; 33 sort(a+1,a+n+1,cp); 34 for(int i=1;i<=n;i++) 35 printf("%d ",a[i]); 36 return 0; 37 }