【解题报告】三校联盟专场一

题目都是11年的网络赛题和现场赛题。。。

Eliminate Witches!

树模拟,直接在字符串上面搞,把特殊符号删掉就是第一部分顺序输出了,然后扫描一遍字符串,用栈维护一下就可以了。

碰到每个单词的第一个字母时入栈,并保存路径;
碰到后括号和逗号时出栈,并保存路径;

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<stack>
10 #define CLR(a) memset(a,0,sizeof(a))
11 typedef long long ll;
12 using namespace std;
13 char s[1000005];
14 int ans[100005],k;
15 int st[100005],sk,_;
16 void init()
17 {
18     k=0;
19     sk=0;
20     _=1;
21 }
22 int co()
23 {
24     int i,ret=0;
25     for(i=0;s[i];i++)
26     {
27         if(i==0||((s[i-1]=='('||s[i-1]==',')&&(s[i]>='a'&&s[i]<='z')))
28         {
29             ret++;
30         }
31     }
32     return ret;
33 }
34 void go()
35 {
36     int i=0,bo=0;
37     for(i=0;i==0||s[i-1];i++)
38     {
39         if(s[i]!='('&&s[i]!=')'&&s[i]!=','&&s[i]!=0)
40         {
41             if(bo==0)
42             {
43                 st[sk++]=_;
44                 _++;
45                 ans[k++]=st[sk-1];
46             }
47             printf("%c",s[i]);
48             bo=1;
49         }
50         else
51         {
52             if(s[i]==')'||s[i]==',')
53             {
54                 sk--;
55                 ans[k++]=st[sk-1];
56             }
57             if(bo)
58             {
59                 bo=0;
60                 printf("
");
61             }
62         }
63     }
64     for(int i=0;i<k-1;i++)
65     {
66         printf("%d %d
",ans[i],ans[i+1]);
67     }
68 }
69 int main()
70 {
71     int t;
72     scanf("%d",&t);
73     while(t--)
74     {
75         init();
76         scanf("%s",s);
77         printf("%d
",co());
78         go();
79         printf("
");
80     }
81     return 0;
82 }
View Code

The Frog's Games

二分枚举步长,每次贪心判断是否可以在m步内跳过去,二分求出最小的可以的步长。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<stack>
10 #define FOR(i,n) for(i=0;i<(n);i++)
11 #define CLR(a) memset(a,0,sizeof(a))
12 #define CIN(a) scanf("%d",&a)
13 typedef long long ll;
14 using namespace std;
15 int a[500005],n,m;
16 int l;
17 int can(int x)
18 {
19     int s=0,ll=0,now=0;
20     for(int i=0;i<m;i++)
21     {
22         while(ll<n&&a[ll]<=s+x)
23         {
24             now=a[ll];
25             ll++;
26         }
27         s=now;
28     }
29     if(s>=l) return true;
30     else return false;
31 }
32 int erfen(int l,int r)
33 {
34     while(l<r)
35     {
36         int mid=(l+r)/2;
37         if(can(mid)) r=mid;
38         else l=mid+1;
39     }
40     printf("%d
",r);
41 }
42 int main()
43 {
44     while(scanf("%d%d%d",&l,&n,&m)!=EOF)
45     {
46         for(int i=0;i<n;i++)
47         {
48             scanf("%d",&a[i]);
49         }
50         sort(a,a+n);
51         a[n]=l;
52         n++;
53         erfen(1,l);
54     }
55     return 0;
56 }
View Code

 Panda

用树状数组维护。

先扫描一下初始状态,然后保存每个wbw字串的位置在树状数组内。

修改时可能改变六个位置的状态,对应的修改一下。

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<string.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<map>
  7 #include<set>
  8 #include<queue>
  9 #include<stack>
 10 #define FOR(i,n) for(i=0;i<(n);i++)
 11 #define CLR(a) memset(a,0,sizeof(a))
 12 #define CIN(a) scanf("%d",&a)
 13 typedef long long ll;
 14 using namespace std;
 15 #define MAXLEN 100005
 16 int c[MAXLEN],n,m;
 17 char s[MAXLEN];
 18 int Lowbit(int x)
 19 {
 20     return x&(-x);
 21 }
 22 /*查询1~end的和*/
 23 int sum(int end)
 24 {
 25     int sum=0;
 26     while(end>0)
 27     {
 28         sum+=c[end];
 29         end-=Lowbit(end);
 30     }
 31     return sum;
 32 }
 33 /*将a[pos]的值加上num*/
 34 void update(int pos,int num)
 35 {
 36     while(pos<=n)
 37     {
 38         c[pos]+=num;
 39         pos+=Lowbit(pos);
 40     }
 41 }
 42 void init()
 43 {
 44     memset(c,0,sizeof(c));
 45     int i,k=0,j=0;
 46     char ss[]="wbw";
 47     for(i=2;i<n;i++)
 48     {
 49         if(s[i-2]=='w'&&s[i-1]=='b'&&s[i]=='w')
 50             update(i-1,1);
 51     }
 52 }
 53 int main()
 54 {
 55     int t,i,z,cas=1;
 56     scanf("%d",&t);
 57     while(t--)
 58     {
 59         scanf("%d%d",&n,&m);
 60         scanf("%s",s);
 61         init();
 62         printf("Case %d:
",cas++);
 63         while(m--)
 64         {
 65             scanf("%d",&z);
 66             if(z){
 67                 char c;
 68                 scanf("%d %c",&i,&c);
 69                 if(s[i]!=c)
 70                 {
 71                     if(i>=2&&s[i-2]=='w'&&s[i-1]=='b'&&s[i]=='w')
 72                     {
 73                         update(i-1,-1);
 74                     }
 75                     if(i>=1&&i<n-1&&s[i-1]=='w'&&s[i]=='b'&&s[i+1]=='w')
 76                     {
 77                         update(i,-1);
 78                     }
 79                     if(i<n-2&&s[i]=='w'&&s[i+1]=='b'&&s[i+2]=='w')
 80                     {
 81                         update(i+1,-1);
 82                     }
 83 
 84                     if(i>=2&&s[i-2]=='w'&&s[i-1]=='b'&&s[i]=='b')
 85                     {
 86                         update(i-1,1);
 87                     }
 88                     if(i>=1&&i<n-1&&s[i-1]=='w'&&s[i]=='w'&&s[i+1]=='w')
 89                     {
 90                         update(i,1);
 91                     }
 92                     if(i<n-2&&s[i]=='b'&&s[i+1]=='b'&&s[i+2]=='w')
 93                     {
 94                         update(i+1,1);
 95                     }
 96                 }
 97                 s[i]=c;
 98             }else{
 99                 int l,r;
100                 scanf("%d%d",&l,&r);
101                 if(r-l<2) printf("0
");
102                 else printf("%d
",sum(r-1)-sum(l));
103             }
104         }
105     }
106     return 0;
107 }
View Code

Hexadecimal View

简单输出一下。。

注意格式。。输出一个16进制可以直接%x输出。行开头的4位16进制可以写%04x。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<stack>
10 #define FOR(i,n) for(i=0;i<(n);i++)
11 #define CLR(a) memset(a,0,sizeof(a))
12 #define CIN(a) scanf("%d",&a)
13 typedef long long ll;
14 using namespace std;
15 char s[5000];
16 void p(int i)
17 {
18     int j;
19     for(j=i;j<i+16&&s[j];j++)
20     {
21         if(s[j]>='a'&&s[j]<='z') printf("%c",s[j]-'a'+'A');
22         else if(s[j]>='A'&&s[j]<='Z') printf("%c",s[j]-'A'+'a');
23         else printf("%c",s[j]);
24     }
25 }
26 int main()
27 {
28     int i,line;
29     while(gets(s))
30     {
31         line=0;
32         for(i=0;s[i];i++)
33         {
34             if(i==0)
35             {
36                 printf("%04x:",line);
37                 line+=16;
38             }
39             if(i!=0&&i%16==0)
40             {
41                 printf(" ");
42                 p(i-16);
43                 printf("
%04x:",line);
44                 line+=16;
45             }
46             if(i%2==0) printf(" ");
47             printf("%x",s[i]);
48         }
49         if(i%16)
50         {
51             while(i%16)
52             {
53                 if(i%2==0) printf(" ");
54                 printf("  ");
55                 i++;
56             }
57         }
58         printf(" ");
59         p(i-16);
60         printf("
");
61     }
62     return 0;
63 }
View Code

Number String

DP:

状态:

dp[i][j]表示第i个数的排列最后一个是j的情况数
dp[i][j]=
{
s[i]='I' : dp[i-1][1]+dp[i-1][2] +...+dp[i-1][j-1]
s[i]='D' : dp[i-1][j]+dp[i-1][j+1]+...+dp[i-1][i]
}

状态转移过程:j结尾的状态:之前的状态是1~i-1的排列,要以j结尾,且新的状态还是1~i的排列,则将之前的1~i-1中比j大的数都加一,然后添加j。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<stack>
10 #define FOR(i,n) for(i=0;i<(n);i++)
11 #define CLR(a) memset(a,0,sizeof(a))
12 #define CIN(a) scanf("%d",&a)
13 typedef long long ll;
14 using namespace std;
15 char s[1005];
16 ll dp[1005][1005],sum[1005];
17 /*
18 dp[i][j]表示第i个数的排列最后一个是j的情况数
19 dp[i][j]=
20 {
21 s[i]='I' : dp[i-1][1]+dp[i-1][2]  +...+dp[i-1][j-1]
22 s[i]='D' : dp[i-1][j]+dp[i-1][j+1]+...+dp[i-1][i]
23 }
24 */
25 const ll MOD=1000000007;
26 int main()
27 {
28     int i,j;
29     while(scanf("%s",s+1)!=EOF)
30     {
31         memset(dp,0,sizeof(dp));
32         int len=strlen(s+1);
33         dp[0][1]=1;
34         for(i=1;i<=len;i++)
35         {
36             sum[0]=0;
37             for(j=1;j<=i+1;j++)
38             {
39                 sum[j]=sum[j-1]+dp[i-1][j];
40                 //printf("sum[%d]=%I64d
",j,sum[j]);
41             }
42             for(j=1;j<=i+1;j++)
43             {
44                 if(s[i]=='I'||s[i]=='?')
45                 {
46                     dp[i][j]+=sum[j-1];
47                     dp[i][j]%=MOD;
48                 }
49                 if(s[i]=='D'||s[i]=='?')
50                 {
51                     dp[i][j]+=sum[i]-sum[j-1];
52                     dp[i][j]%=MOD;
53                 }
54                 //printf("dp[%d][%d]=%I64d
",i,j,dp[i][j]);
55             }
56         }
57         ll ans=0;
58         for(j=1;j<=len+1;j++)
59         {
60             ans+=dp[len][j];
61             ans%=MOD;
62         }
63         printf("%I64d
",ans);
64     }
65     return 0;
66 }
View Code

The kth great number

用小顶堆维护,添加一个数之后把最小的数去掉,使优先队列内只有k个元素,询问的时候输出取出队头。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<queue>
10 #include<stack>
11 #define FOR(i,n) for(i=0;i<(n);i++)
12 #define CLR(a) memset(a,0,sizeof(a))
13 #define CIN(a) scanf("%d",&a)
14 typedef long long ll;
15 using namespace std;
16 priority_queue<int,vector<int>,greater<int> > P;
17 int main()
18 {
19     int q,k,a;
20     char c[3];
21     while(scanf("%d%d",&q,&k)!=EOF)
22     {
23         while(!P.empty()) P.pop();
24         while(q--)
25         {
26             scanf("%s",c);
27             if(c[0]=='I')
28             {
29                 scanf("%d",&a);
30                 P.push(a);
31                 if(P.size()>k)
32                 {
33                     P.pop();
34                 }
35             }
36             else
37             {
38                 printf("%d
",P.top());
39             }
40         }
41     }
42     return 0;
43 }
View Code

题目来源:HDU

4041 Eliminate Witches!
4004 The Frog's Games
4046 Panda
4054 Hexadecimal View
4055 Number String
4006 The kth great number

原文地址:https://www.cnblogs.com/syiml/p/4491560.html