Codeforces round 171 div2

Source: Internet
Author: User

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;}



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.