现在的位置: 首页 > 综合 > 正文

Codeforces Round #171 (Div. 2)

2012年08月05日 ⁄ 综合 ⁄ 共 2592字 ⁄ 字号 评论关闭

a. 最近做过的最痛苦的a题。 平时a题最多也就5分钟,可是这题我却卡了近一个小时。

题意很简单,以一种规则画圈, 然后求给出点需要转多少次方向.

找规律方法

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <algorithm>
 5 #include <iostream>
 6 using namespace std;
 7 
 8 
 9 int main()
10 {
11     int x,y;
12     scanf("%d%d",&x,&y);
13     int sum;
14     if(x>0&&x*-1==y)
15     {
16         sum=4+4*(x-1);
17         printf("%d",sum);
18         return 0;
19     }
20     if(abs(x)>=abs(y))
21     {
22         if(x>=0)
23         {
24             if(x==0)
25             {
26                 sum=0;
27             }
28             else
29             {
30                 sum=4*(x-1)+1;
31                 if(-1*y==x-1) sum--;
32             }
33         }
34         else
35         {
36             sum=3+4*(-1*x-1);
37             if(-1*x==y) sum--;
38         }
39     }
40     else
41     {
42         if(y>=0)
43         {
44             sum=2+4*(y-1);
45             if(x==y) sum--;
46         }
47         else
48         {
49             sum=4+4*(-1*y-1);
50             if(x==y) sum--;
51         }
52     }
53     printf("%d",sum);
54     return 0;
55 }
模拟

 

b. 队列简单题

#include <stdio.h>
#include <string.h>
#define N 100100
int g[N],k[N];

int main()
{
    int n,t;
    scanf("%d%d",&n,&t);
    int qf=0,qd=0;
    int sum=0;
    int mx=0;
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        int tmp;
        scanf("%d",&tmp);
        g[i]=tmp;
        if(tmp>t) 
        {
            cnt=0;
            qd=i+1;
            sum=0;
            continue;
        }
        if(sum+tmp<=t)
        {
            sum+=tmp;
            cnt++;
            if(cnt>mx) mx=cnt;
        }
        else
        {
            while(sum+tmp>t)
            {
                sum-=g[qd++];
                cnt--;
            }
            sum+=tmp;
            cnt++;
            if(cnt>mx) mx=cnt;
        }
    }
    printf("%d",mx);
    return 0;
}

 

c. 判断给定区域内的线段是否成梯形(单调递增 或单调递减或 先整后减), 可以用用两个数组记录整个线段的变换情况。 然后在判断就行了。

 

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 100100
#define INF 0x3fffffff

int g[N];
int mi[N],mx[N];

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&g[i]);
    int qd=1;
    int tmp=-1;
    for(int i=1;i<=n;i++)
    {
        if(g[i]>=tmp)
        {
            tmp=g[i];
        }
        else
        {
            tmp=g[i];
            for(int j=qd;j<=i-1;j++)
            {
                mx[j]=i-1;
            }
            qd=i;
        }
        if(i==n)
        {
            for(int j=qd;j<=i;j++)
                mx[j]=i;
        }
    }
    qd=1;
    tmp = INF;
    for(int i=1;i<=n;i++)
    {
        if(g[i]<=tmp)
        {
            tmp=g[i];
        }
        else
        {
            tmp=g[i];
            for(int j=qd;j<=i-1;j++)
            {
                mi[j]=i-1;
            }
            qd=i;
        }
        if(i==n)
        {
            for(int j=qd;j<=i;j++)
            {
                mi[j]=i;
            }
        }
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(mx[x]>=y||mi[x]>=y) printf("Yes\n");
        else
        {
            if(mi[mx[x]]>=y) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

 

e. 用dp或者贪心都可以做, 关键是要将问题模型转换, 题中所说的可以增加2^k 或  -2^k . 实际上的意思是用一次操作改变一位,或用两次操作改变一段. 这样就可以想到贪心规则,和状态转移方程了...

DP 解法

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 #define N 1000100
 7 
 8 char g[N];
 9 int save[N];
10 int dp[N];
11 int dp1[N];
12 
13 int min1(int x,int y)
14 {
15     if(x>y) return y;
16     else return x;
17 }
18 int main()
19 {
20     scanf("%s",g);
21     int i=0;
22     int cnt=0;
23     while(g[i]=='0')
24     {
25         i++;
26     }
27     int len = strlen(g);
28     if(i==len)
29     {
30         printf("0");
31         return 0;
32     }
33     char tmp='1';
34     int tcnt=0;
35     for(;i<=len;i++)
36     {
37         if(tmp==g[i]&&i!=len)
38         {
39             tcnt++;
40         }
41         else
42         {
43             tmp=g[i];
44             save[cnt++]=tcnt;
45             tcnt=1;
46         }
47     }
48     if(cnt%2==0)  cnt--; // 当最后一位0的时候,省略
49 
50     dp[0]=save[0];
51     dp1[0]=2;
52 
53     for(int j=2;j<cnt;j++)
54     {
55         dp[j]=min1(dp[j-2],dp1[j-2])+save[j];
56         dp1[j]=min1(min1(dp[j-2]+2,dp1[j-2]+save[j-1]),dp1[j-2]+2);
57         j++;
58     }
59     printf("%d",min1(dp[cnt-1],dp1[cnt-1]));
60      return 0;
61 }

 

 

 

 

抱歉!评论已关闭.