A. Rewards
Question
#include<cstdio>#include<iostream>#include<cstring>using namespace std;int main(){ int a1,a2,a3,b1,b2,b3,s,t1,t2,sum1,sum2; while(scanf("%d%d%d",&a1,&a2,&a3)!=EOF) { scanf("%d%d%d",&b1,&b2,&b3); scanf("%d",&s); sum1 = a1+a2+a3; sum2 = b1+b2+b3; if(sum1>=5) { t1 = sum1/5; if(sum1%5) t1++; } else if(sum1>0) t1 = 1; else t1 = 0; if(sum2>=10) { t2 = sum2/10; if(sum2%10) t2++; } else if(sum2>0) t2 = 1; else t2 = 0; if(t1+t2>s) puts("NO"); else puts("YES"); } return 0;}
B. suffix Structures
Question: Here are two strings. To change string a to string B, if you only need to delete some characters, you can output the automaton
If an array is output only by exchanging some characters, if both operations are required, the both is output.
If neither of them works, the need tree is output.
Algorithm:
This is actually a complicated situation. You must keep your mind clear and clear ~
1. First, if the two strings are the same, the output array is used.
2. If the length of string a is less than the length of string B or the number or type of the corresponding letter in string B is insufficient, it is a need tree.
3. If the length of string a is equal to the length of string B, and the corresponding letters in string B can be found in string a, array is output.
4. If string a is longer than string B, and the letters in string B appear in sequence in string a, the output is automatic.
If the order is different, the both is output.
#include<cstdio>#include<iostream>#include<cstring>#include<vector>using namespace std;char s1[110],s2[110];vector<int> c;int cnt1[30],cnt2[30];int main(){ int flag1,flag2,d,flag; while(scanf("%s%s",s1,s2)!=EOF) { if(strcmp(s1,s2)==0) { printf("array\n"); continue; } flag1 = flag2 = flag = 0; c.clear(); memset(cnt1,0,sizeof(cnt1)); memset(cnt2,0,sizeof(cnt2)); int len1 = strlen(s1); int len2 = strlen(s2); if(len1>len2) flag1 = 1; for(int i=0;i<len2;i++) cnt2[s2[i]-'a']++; for(int j=0;j<len1;j++) cnt1[s1[j]-'a']++; for(int i=0;i<len2;i++) { if(cnt2[s2[i]-'a'] > cnt1[s2[i]-'a']) { flag = 1; break; } } if(flag || len1<len2) { printf("need tree\n"); continue; } for(int i=0;i<len1;i++) { if(s1[i]==s2[0]) c.push_back(i); } for(int i=0;i<c.size();i++) { int t = 1; for(int j=c[i]+1;j<len1;j++) { if(s1[j]==s2[t]) t++; } if(t == len2) { flag2 = 1; break; } } if(flag1 && flag2) printf("automaton\n"); else if(flag1 && !flag2) printf("both\n"); else if(!flag1 && !flag2) printf("array\n"); } return 0;}
C. Painting fence
Question: There are n wooden bars with the length of AI. Then there is a paint brush. The width of the wood bar and the width of the paint brush are both 1.
All wood strips are painted. And the paint brush must have wood blocks. The minimum number of clicks required.
Algorithm: memory-based search
1. The following must be a horizontal brush.
2. After the common lengths below are finished, the wooden bars are divided into several broken blocks, each of which is composed of the upper half of several wooden bars that are not painted.
Each part is either a vertical brush or a horizontal brush. In this case, the number of times of the two methods is compared, whichever is smaller. The part of [L, R] needs to be flushed vertically.
In R-l + 1, the public part is refreshed in a horizontal manner, and the above part is divided into several blocks, so the same sub-problem occurs again. Use DFS recursion.
#include<cstdio>#include<iostream>#include<cstring>#define maxn 5010using namespace std;typedef long long ll;ll a[maxn];ll min(ll x,ll y){ return x<y?x:y;}ll work(int l,int r,int cen){ ll mi = a[l]; for(int i=l+1;i<=r;i++) mi = min(mi,a[i]); ll sum = mi-cen,s = r-l+1; int last = l; for(int i=l;i<=r;i++) { if(a[i]==mi) { if(last<i) sum+=work(last,i-1,mi); last = i+1; } } if(last<=r) sum+=work(last,r,mi); return min(sum,s);}int main(){ int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); ll ans = work(1,n,0); printf("%I64d\n",ans); } return 0;}
D. Multiplication table
Question: Which is the maximum K number in the multiplication table of N rows and M columns.
For example, the multiplication table of 2*3 is 1 2 3.
2 4 6
Algorithm: Binary Search.
Because the maximum number is N * m = 25*10 ^ 10, think of binary. The number at K is that K is smaller than or equal to his number (this statement is not accurate ),
It is the first such minimum number.
Take full advantage of the characteristics of the multiplication table, each row is the number of rows multiplied by 1-M. Therefore, the ratio less than or equal to X is Min (M, X/I ).
P.s... I didn't think of this solution anyway... O (Clerk □clerk) o... Learning...
#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;typedef long long ll;ll k,n,m;ll min(ll x,ll y){ return x<y?x:y;}ll check(ll x){ ll sum = 0; for(int i=1;i<=n;i++) sum += min(m,x/i); return sum;}int main(){ ll ans; while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF) { ll l = 1,r = n*m; while(l<=r) { ll mid = (l+r)>>1; if(check(mid)>=k) { ans = mid; r = mid-1; } else l = mid+1; } printf("%I64d\n",ans); } return 0;}