http://vjudge.net/contest/view.action?cid=55702#overview
12656 - Almost Palindrome http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4394
先把原串处理成只有小写的,然后枚举每一个位置,可以以它为中心向两边扩展,回文可以是奇数,也可以是偶数,分类讨论,如果两边不一样,那么容量加一,容量小于k都行。
1 #include<cstdio> 2 #include<cctype> 3 const int M=1024; 4 char a[M],b[M]; 5 int p[M]; 6 int main(){ 7 int n,cas=1; 8 while(~scanf("%d",&n)){ 9 getchar(); 10 gets(a); 11 int lb=0; 12 for(int i=0;a[i];i++){ 13 if(isalpha(a[i])){ 14 p[lb]=i; 15 b[lb++]=tolower(a[i]); 16 } 17 } 18 int big=0,id; 19 for(int i=0;i<lb;i++){ 20 int cnt=0; 21 for(int j=0;i-j>=0&&i+j<lb;j++){///奇数 22 if(b[i-j]!=b[i+j]) cnt++; 23 if(cnt>n) break; 24 int prelen=p[i+j]-p[i-j]+1; 25 if(big<prelen){ 26 big=prelen; 27 id=p[i-j]; 28 } 29 } 30 cnt=0; 31 for(int j=0;i-j>=0&&i+j+1<lb;j++){///偶数 32 if(b[i-j]!=b[i+j+1]) cnt++; 33 if(cnt>n) break; 34 int prelen=p[i+j+1]-p[i-j]+1; 35 if(big<prelen){ 36 big=prelen; 37 id=p[i-j]; 38 } 39 } 40 } 41 printf("Case %d: %d %d ",cas++,big,id+1); 42 } 43 return 0; 44 }
12658 - Character Recognition? http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4396
123识别,找不同。
1 #include<cstdio> 2 char a[8][64]; 3 int main(){ 4 int n; 5 while(~scanf("%d",&n)){ 6 for(int i=0;i<5;i++){ 7 scanf("%s",a[i]); 8 } 9 for(int i=0,y=0;i<n;i++,y+=4){ 10 if(a[0][y]=='.'){ 11 printf("1"); 12 continue; 13 } 14 if(a[3][y+2]=='.'){ 15 printf("2"); 16 continue; 17 } 18 printf("3"); 19 } 20 puts(""); 21 } 22 return 0; 23 }
12661 - Funny Car Racing http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4399
bfs,记忆化搜索dp,注意t>a的边就别加了
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 typedef long long LL; 7 const LL inf=0x3f3f3f3f3f3f3f3fLL; 8 const int M=310; 9 struct G{ 10 struct E{ 11 int v,next,a,b,t; 12 }e[50010]; 13 int le,head[M]; 14 void init(){ 15 le=0; 16 mt(head,-1); 17 } 18 void add(int u,int v,int a,int b,int t){ 19 e[le].v=v; 20 e[le].a=a; 21 e[le].b=b; 22 e[le].t=t; 23 e[le].next=head[u]; 24 head[u]=le++; 25 } 26 }g; 27 LL dp[M]; 28 queue<int> q; 29 void bfs(int s){ 30 for(int i=0;i<M;i++){ 31 dp[i]=inf; 32 } 33 dp[s]=0; 34 while(!q.empty()) q.pop(); 35 q.push(s); 36 while(!q.empty()){ 37 int u=q.front(); 38 q.pop(); 39 LL pretime=dp[u],cost; 40 for(int i=g.head[u];~i;i=g.e[i].next){ 41 int v=g.e[i].v; 42 int a=g.e[i].a; 43 int b=g.e[i].b; 44 int t=g.e[i].t; 45 LL now=pretime%(a+b); 46 if(now+t<=a){ 47 cost=t; 48 } 49 else{ 50 cost=a+b-now+t; 51 } 52 cost+=pretime; 53 if(dp[v]>cost){ 54 dp[v]=cost; 55 q.push(v); 56 } 57 } 58 } 59 } 60 int main(){ 61 int n,m,s,t,cas=1; 62 while(~scanf("%d%d%d%d",&n,&m,&s,&t)){ 63 g.init(); 64 while(m--){ 65 int u,v,a,b,c; 66 scanf("%d%d%d%d%d",&u,&v,&a,&b,&c); 67 if(c>a) continue; 68 g.add(u,v,a,b,c); 69 } 70 bfs(s); 71 printf("Case %d: %lld ",cas++,dp[t]); 72 } 73 return 0; 74 }
12662 - Good Teacher http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4400
简单题 注意细节,最坏情况也就是n^2,预处理出最近的。
1 #include<cstdio> 2 #include<cstring> 3 struct G{ 4 char name[8],left[8],right[8]; 5 int L,R; 6 }g[128]; 7 int main(){ 8 int n,m,q; 9 while(~scanf("%d",&n)){ 10 for(int i=1;i<=n;i++){ 11 scanf("%s",g[i].name); 12 } 13 for(int i=1;i<=n;i++){ 14 if(g[i].name[0]=='?'){ 15 int id=i; 16 for(int j=i;j<=n;j++){ 17 if(g[j].name[0]!='?'){ 18 id=j; 19 break; 20 } 21 } 22 g[i].R=id-i; 23 if(id==i) g[i].R=999; 24 strcpy(g[i].right,g[id].name); 25 id=i; 26 for(int j=i;j>=1;j--){ 27 if(g[j].name[0]!='?'){ 28 id=j; 29 break; 30 } 31 } 32 g[i].L=i-id; 33 if(id==i) g[i].L=999; 34 strcpy(g[i].left,g[id].name); 35 } 36 } 37 scanf("%d",&m); 38 while(m--){ 39 scanf("%d",&q); 40 if(g[q].name[0]!='?'){ 41 puts(g[q].name); 42 continue; 43 } 44 if(g[q].L==g[q].R){ 45 printf("middle of %s and %s ",g[q].left,g[q].right); 46 continue; 47 } 48 if(g[q].L<g[q].R){ 49 for(int i=0;i<g[q].L;i++){ 50 printf("right of "); 51 } 52 puts(g[q].left); 53 continue; 54 } 55 for(int i=0;i<g[q].R;i++){ 56 printf("left of "); 57 } 58 puts(g[q].right); 59 } 60 } 61 return 0; 62 }
12663 - High bridge, low bridge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4401
离线的区间累加和是可以左++右--on处理的,当然如果是线段树树状数组都会多个logn,不好 不好
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int M=100010; 5 int a[M],lazy[M]; 6 int main(){ 7 int n,m,k,cas=1; 8 while(~scanf("%d%d%d",&n,&m,&k)){ 9 for(int i=0;i<n;i++){ 10 scanf("%d",&a[i]); 11 lazy[i]=0; 12 } 13 sort(a,a+n); 14 int prehigh=1,nowa,nowb; 15 while(m--){ 16 scanf("%d%d",&nowa,&nowb); 17 int s=upper_bound(a,a+n,prehigh)-a; 18 int e=upper_bound(a,a+n,nowa)-a; 19 lazy[s]++; 20 lazy[e]--; 21 prehigh=nowb; 22 } 23 int now=0,ans=0; 24 for(int i=0;i<n;i++){ 25 now+=lazy[i]; 26 if(now>=k) ans++; 27 } 28 printf("Case %d: %d ",cas++,ans); 29 } 30 return 0; 31 }
12664 - Interesting Calculator http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4402
听说搜索剪枝能过,因为时限大吧,一开始想二维dp,但是不对,用dp i j 表示第 i 个数在第 j 步到达的最小花费,因为可能一步就加了1,所以第二维也可能达到10^5,完全干不动。 仔细考虑了一下,除了*0这种操作, 其余都会使得当前的数变大。所以当x不等于0时,dp 0 只要1步, 然后从小往大的更新最小费用, 因为除了这种情况 其他的值都是从比自己小的值推过来的。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long LL; 5 const LL inf=0x3f3f3f3f3f3f3f3fLL; 6 const int M=100010; 7 LL dp[M]; 8 int step[M]; 9 int val[8][16]; 10 int main(){ 11 int x,y,cas=1; 12 while(~scanf("%d%d",&x,&y)){ 13 for(int i=0;i<3;i++){ 14 for(int j=0;j<10;j++){ 15 scanf("%d",&val[i][j]); 16 } 17 } 18 for(int i=0;i<=y;i++){ 19 dp[i]=inf; 20 step[i]=0x3f3f3f3f; 21 } 22 dp[x]=0; 23 step[x]=0; 24 if(x){ 25 dp[0]=val[2][0]; 26 step[0]=1; 27 } 28 for(int i=0;i<y;i++){ 29 for(int j=0;j<3;j++){ 30 for(int k=0;k<10;k++){ 31 int next; 32 if(j==0){ 33 next=i*10+k; 34 } 35 else if(j==1){ 36 next=i+k; 37 } 38 else{ 39 next=i*k; 40 } 41 if(next>y) continue; 42 LL cost=dp[i]+val[j][k]; 43 if(dp[next]>cost){ 44 dp[next]=cost; 45 step[next]=step[i]+1; 46 } 47 else if(dp[next]==cost){ 48 step[next]=min(step[next],step[i]+1); 49 } 50 } 51 } 52 } 53 printf("Case %d: %lld %d ",cas++,dp[y],step[y]); 54 } 55 return 0; 56 }
12665 - Joking with Fermat's Last Theorem http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4403
a,b在1000就够了,所以可以暴力的去判断
1 #include<cstdio> 2 int x,y,cas=1; 3 bool ok(int a){ 4 return a>=x&&a<=y; 5 } 6 int main(){ 7 while(~scanf("%d%d",&x,&y)){ 8 int ans=0; 9 for(int i=1;i<1010;i++){ 10 for(int j=1;j<1010;j++){ 11 if(ok(i)&&ok(j)){ 12 int left=i*i*i+j*j*j; 13 if(left%10==3){ 14 int c=left/10; 15 if(ok(c)){ 16 ans++; 17 } 18 } 19 } 20 } 21 } 22 printf("Case %d: %d ",cas++,ans); 23 } 24 return 0; 25 }
12667 - Last Blood http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4405
唯一的坑就是如果一个队ac一个题,那要算最早ac的时间。
1 #include<cstdio> 2 struct G{ 3 int t,id; 4 }g[16]; 5 char p[4],yes[8]; 6 bool mat[16][128]; 7 int main(){ 8 int n,t,m,x,y; 9 while(~scanf("%d%d%d",&n,&t,&m)){ 10 for(int i=0;i<n;i++){ 11 g[i].t=-1; 12 for(int j=0;j<=t;j++){ 13 mat[i][j]=false; 14 } 15 } 16 while(m--){ 17 scanf("%d%d%s%s",&x,&y,p,yes); 18 if(yes[0]=='N') continue; 19 int pp=p[0]-'A'; 20 if(mat[pp][y]) continue; 21 mat[pp][y]=true; 22 g[pp].t=x; 23 g[pp].id=y; 24 } 25 for(int i=0;i<n;i++){ 26 printf("%c ",i+'A'); 27 if(g[i].t!=-1){ 28 printf("%d %d ",g[i].t,g[i].id); 29 } 30 else{ 31 puts("- -"); 32 } 33 } 34 } 35 return 0; 36 }
end