【解题报告】三校联盟专场一
题目都是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("\n"); 61 } 62 } 63 } 64 for(int i=0;i<k-1;i++) 65 { 66 printf("%d %d\n",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\n",co()); 78 go(); 79 printf("\n"); 80 } 81 return 0; 82 }
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\n",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 }
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:\n",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\n"); 102 else printf("%d\n",sum(r-1)-sum(l)); 103 } 104 } 105 } 106 return 0; 107 }
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("\n%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("\n"); 61 } 62 return 0; 63 }
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\n",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\n",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\n",ans); 64 } 65 return 0; 66 }
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\n",P.top()); 39 } 40 } 41 } 42 return 0; 43 }
题目来源:HDU
4041 Eliminate Witches!
4004 The Frog's Games
4046 Panda
4054 Hexadecimal View
4055 Number String
4006 The kth great number