简单题,直接判断替换,然后判断即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <algorithm> #include <math.h> using namespace std; char s[110],t[119]; int chgs(char c) { if(c=='A') return 0; if(c=='T') return 1; if(c=='C') return 2; if(c=='G') return 3; return 4; } int chgt(char c) { if(c=='U') return 0; if(c=='A') return 1; if(c=='G') return 2; if(c=='C') return 3; return 4; } int main(int argc, const char * argv[]) { int T; cin>>T; while (T--) { int n; cin>>n; scanf("%s%s",s,t); int flag=0; for(int i=0;i<n;i++) { int x=chgs(s[i]); int y=chgt(t[i]); if(x!=y) flag=1; } if(flag==0) printf("YES "); else printf("NO "); } return 0; }
简单的博弈题,模拟几组数据就可以发现解法了,把n分奇偶讨论下就好了。三行代码就可以搞定了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <algorithm> #include <math.h> using namespace std; int main(int argc, const char * argv[]) { int T; cin>>T; while (T--) { int n; cin>>n; cout<<n%2<<endl; } return 0; }
挺有意思的题目。 好久没写线段树成段更新了,写了很久这题才做出来,不然就可以做D题了。
解法:找出序列中最小且最靠右的一个数,这个数的位置就是当前最大的数,然后把这个数后面所有数减1(线段树),把这个位置的数设成INF(防止干扰后续操作),然后重复找最小的最靠右的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <algorithm> #include <math.h> using namespace std; #define N 200000 int L[N],R[N],flag[N],mi[N],mipos[N]; int tg[50200],g[50500]; void UP(int s) { if(mi[2*s]<mi[2*s+1]) { mi[s]=mi[2*s]; mipos[s]=mipos[2*s]; } else { mi[s]=mi[2*s+1]; mipos[s]=mipos[2*s+1]; } } void build(int l,int r,int s) { L[s]=l; R[s]=r; flag[s]=-1; if(l==r) { flag[s] = -1; mi[s] = g[l]; mipos[s] = l; return ; } int mid = (l+r)/2; build(l,mid,2*s); build(mid+1,r,2*s+1); UP(s); } void DOWN(int s) { if(flag[s]!=-1) { if(flag[2*s]!=-1) { flag[2*s] += flag[s]; mi[2*s] -= flag[s]; }else { mi[2*s] -= flag[s]; flag[2*s] = flag[s]; } if(flag[2*s+1]!=-1){ mi[2*s+1] -= flag[s]; flag[2*s+1] += flag[s]; } else{ mi[2*s+1] -= flag[s]; flag[2*s+1] = flag[s]; } flag[s]=-1; } } void modify_one(int p,int inf,int s) { if(L[s]==p&&R[s]==p) { mi[s]=inf; flag[s]=-1; return ; } DOWN(s); int mid=(L[s]+R[s])/2; if(p<=mid) modify_one(p, inf, 2*s); else modify_one(p, inf, 2*s+1); UP(s); } /* void query(int l,int r,int s) { if(l==L[s]&&r==R[s]) { if(flag[s]!=-1) { mi[s] -= flag[s]; flag[s]=-1; } return ; } DOWN(s); int mid=(L[s]+R[s])/2; if(r<=mid) query(l,r,2*s); else if(l>mid) query(l,r,2*s+1); else { query(l,r,2*s+1); } } */ void modify_seq(int l,int r,int s) { if(l==L[s]&&r==R[s]) { mi[s]--; if(flag[s]==-1) flag[s]=1; else flag[s] += 1; return ; } DOWN(s); int mid=(L[s]+R[s])/2; if(r<=mid) modify_seq(l, r,2*s); else if(l>mid) modify_seq(l, r, 2*s+1); else { modify_seq(l,mid,2*s); modify_seq(mid+1, r, 2*s+1); } UP(s); } int ans[50500]; int main(int argc, const char * argv[]) { int T; cin>>T; while (T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",tg+i); } tg[0]=0; for(int i=1;i<=n;i++) g[i] = tg[i] - tg[i-1]; //然后 build(1,n,1); for(int i=n;i>=1;i--) { int tmp = mipos[1]; ans[tmp]=i; modify_one(tmp, 100000000, 1); if(tmp!=n) modify_seq(tmp+1, n, 1); } //modify_one(1,100000000,1); //query(1,n,1); //modify_seq(1,10,1); for(int i=1;i<n;i++) printf("%d ",ans[i]); printf("%d ",ans[n]); } return 0; }
这题其实应该挺水的,类似于求树的直径,DFS两次即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// // main.cpp // hdu5593 // // Created by 陈加寿 on 15/12/9. // Copyright (c) 2015年 陈加寿. All rights reserved. // #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <stdlib.h> #include <math.h> #include <algorithm> using namespace std; #define N 500500 struct node { int from,to,next; }edge[N]; int pre[N],cnt; int save[N][11]; int tmp[11]; long long ans; int k; void add_edge(int u,int v) { edge[cnt].to=v; edge[cnt].from=u; edge[cnt].next=pre[u]; pre[u]=cnt++; } void first_dfs(int s,int fa) { memset(save[s],0,sizeof(save[s])); for(int p=pre[s];p!=-1;p=edge[p].next) { int to=edge[p].to; if(to==fa) continue; first_dfs(to, s); for(int i=0;i<k;i++) { save[s][i+1] += save[to][i]; } } save[s][0]=1; } void second_dfs(int s,int fa) { int sum=0; for(int i=0;i<=k;i++) { save[s][i] += tmp[i]; sum+=save[s][i]; } ans^=sum; for(int p=pre[s];p!=-1;p=edge[p].next) { int to=edge[p].to; if(to==fa) continue; //生成tmp for(int i=1;i<=k;i++) { tmp[i] = save[s][i-1]; } for(int i=2;i<=k;i++) { tmp[i] -= save[to][i-2]; } second_dfs(to, s); } } int main() { int T; cin>>T; while(T--) { long long n,a,b; cin>>n>>k>>a>>b; cnt=0; memset(pre,-1,sizeof(pre)); for(int i=2;i<=n;i++) { int to = (a*i+b)%(i-1)+1; add_edge(to,i); } ans=0; first_dfs(1,0); second_dfs(1,0); memset(tmp,0,sizeof(tmp)); cout<<ans<<endl; } return 0; }