Http://codeforces.com/contest/279/problem/A
A: You can draw a drawing on your own to understand the law. Let's give you a point and ask how many turns this point has taken on the spiral.
Thought: I did it through simulation. Because the data volume is not large, it is violent from the inside out to check whether it is on the current line segment.
#include <iostream>#include <string.h>#include <stdio.h>using namespace std;int dir[4][2]={1,0,0,1,-1,0,0,-1};int main(){ int x,y; scanf("%d%d",&x,&y); int sx=0,sy=0,ans=0,d=0,len=1,tx=0,ty=0; while(1) { int num=2; while(num--) { //printf("%d %d\n",tx,ty); d%=4; sx=tx,sy=ty; tx=sx+len*dir[d][0],ty=sy+len*dir[d][1]; if(d%2) { if(x==sx&&(y-sy)*(y-ty)<=0) { printf("%d\n",ans); return 0; } } else { if(y==sy&&((x-sx)*(x-tx))<=0) { printf("%d\n",ans); return 0; } } ans++; d++; } len++; } return 0;}
Http://codeforces.com/contest/279/problem/ B
B: Give You n numbers. The longest continuous interval is the sum of the numbers in the interval not greater than T.
Train of Thought: At first glance, I think it is better to have two points. We scan from left to right, set L to the left endpoint of the current range, initially 1, set the current traversal to I, then if sum [L, I]> T, then, I add L ++ until sum [L, I] <= T. At this time, I-l + 1 is the maximum value of the interval ending with I and is set to TMP, we can find the maximum value of TMP in the traversal process. The time complexity is O (n ).
#include <iostream>#include <string.h>#include <stdio.h>#define maxn 100010using namespace std;int a[maxn];int max(int a,int b){ return a>b?a:b;}int main(){ //freopen("dd.txt","r",stdin); int n,t,i; scanf("%d%d",&n,&t); for(int i=n;i>=1;i--) scanf("%d",&a[i]); int l=0,sum=0,ans=0; for(i=1;i<=n;i++) { sum+=a[i]; if(sum<=t) ans=max(ans,i-l); else { while(sum>t) { sum-=a[++l]; } ans=max(ans,i-l); } } printf("%d\n",ans); return 0;}
Http://codeforces.com/contest/279/problem/C
C: give you n numbers a [1] ~ A [n]: ask if the range [L, R] is non-decreasing when the previous segment is met, and the latter segment is not increasing. (The first and second sections can be blank)
Idea: set MI [I] And ma [I] to indicate the left end of a [I], non-decreasing substring and the left end of non-incrementing substring respectively. This can be solved within the O (n) complexity. If Mi [R] <= L or ma [I] <= L, it indicates that the interval [L, R] is a non-decreasing string or a non-incrementing string, and the output is yes, otherwise, set Po = mi [R], indicating that the range [Po, R] is not an ascending string. If Ma [po] <= L, it indicates that the range [L, po] is not decreasing, [Po, R] is not incremental, and the output is yes; otherwise, no is output.
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#define maxn 100010using namespace std;int a[maxn];int ma[maxn],mi[maxn];int main(){ //freopen("dd.txt","r",stdin); int n,i,q; scanf("%d%d",&n,&q); for(i=1;i<=n;i++) scanf("%d",&a[i]); ma[1]=mi[1]=1; for(i=2;i<=n;i++) { if(a[i]>a[i-1]) { ma[i]=ma[i-1]; mi[i]=i; } else if(a[i]<a[i-1]) { ma[i]=i; mi[i]=mi[i-1]; } else { ma[i]=ma[i-1]; mi[i]=mi[i-1]; } } while(q--) { int l,r; scanf("%d%d",&l,&r); if(ma[r]<=l||mi[r]<=l) { printf("Yes\n"); } else { int po=mi[r]; if(ma[po]<=l) printf("Yes\n"); else printf("No\n"); } } return 0;}
Http://codeforces.com/contest/279/problem/D
D: I read the conclusion report of becauseofyou. The Code basically references the report of becauseofyou. The first state is to compress DP.
The State is represented in binary format. 1 of the highest bits of State X is the I bit, indicating that a [I] is combined with the preceding number, 1 before the I bit indicates that the current State has saved a [J] (0 <= j <I and the J bit of X is 1 ), 0 indicates that the current status is not sure whether a [J] is saved (0 <= j <I and the J-bit of X is 0 ). set DP [x] to the minimum number of variables in the X state. In this case, we require DP [1 <(n-1)]. Because each number is obtained one by one, when the State X is obtained again, the previous State must contain the number of the previous requirement (that is, a [I-1]), if a [I] = A [J] + A [k] (0 <= j, k <I ), indicates that a [I] is transferred by a [J] And a [K], so the previous State must save a [J] And a [K], so the state transition equation came out.
Note that if num is set to State X and the number of 1 is expressed in binary, DP [x] should be at least num, which can be understood by the meaning of State X.
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#define inf 2100000000using namespace std;int a[25],pow[23];int dp[1<<23],n;void init(){ memset(dp,-1,sizeof(dp)); pow[0]=1; for(int i=1;i<23;i++) pow[i]=2*pow[i-1];}int min(int a,int b){ return a<b?a:b;}int max(int a,int b){ return a>b?a:b;}int dfs(int x){ if(dp[x]!=-1) return dp[x]; int num=__builtin_popcount(x); int ans=inf,tmp; for(int i=n-1;i>=0;i--) { if(x&pow[i]) { int tt=(x^pow[i])|pow[i-1]; for(int j=i-1;j>=0;j--) { for(int k=j;k>=0;k--) { if(a[i]==a[j]+a[k]) { tmp=dfs(tt|pow[j]|pow[k]); if(tmp!=inf) ans=min(ans,max(tmp,num)); } } } break; } } dp[x]=ans; return ans;}int main(){ //freopen("dd.txt","r",stdin); int i; init(); scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&a[i]); dp[1]=1; int ans=dfs(pow[n-1]); if(ans==inf) ans=-1; printf("%d\n",ans); return 0;}
Http://codeforces.com/contest/279/problem/E
E: Give You A binary representation of the number a [1] ~ A [n] is used to calculate the number in the form of least 2 ^ K and-2 ^ K. Their sum is equal to the given number.
Idea: greedy is also acceptable, but it is quite simple for me to do it through DP. A simple conclusion is that the K numbers used are different.
Set DP [I] to the minimum value required by the last I-digit. We traverse from the back to the front.
When a [I] = 1, we can directly add 2 ^ I, that is, DP [I] = DP [I + 1], or we can use 2 ^ (I + 1)-2 ^ J (0 <= j <I) to set the I bit to 1, but this is not complete yet, we also need to add DP [n-J + 1], and for 0 in [I, n-J, we also use-2 ^ X (I <x <= N-J and a [x] = 0) to minimize the number obtained, it is necessary to make the DP [n-J + 1] + 2 + num (Num is the number of 0 in the range [I, n-J]) the smallest, we set this value to W [x] for different positions, which seems to require O (N ^ 2) Complexity. Otherwise, we can find that, if the position Po is the smallest, in fact, if a [I] = 1, num remains the same, W [po] is the smallest.
If a [I] = 0, num ++, W [po] ++. At this time, only w [I] may be less than W [po]. Let's compare the update. The final complexity can reach O (n ).
(The expression capability is the same. I don't understand it at all. Let's look at the code)
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;char str[1000010];int dp[1000010];int min(int a,int b) { return a>b?b:a; }int main(){ // freopen("dd.txt","r",stdin); int i,tmp=0; scanf("%s",str+1); int n=strlen(str+1); dp[n]=str[n]-'0'; for(i=n-1;i>=1;i--) { if(str[i]=='1') dp[i]=min(dp[i+1]+1,tmp+2); else { tmp++; dp[i]=dp[i+1]; tmp=min(tmp,dp[i]); } } printf("%d\n",dp[1]); return 0;}