题目链接: https://www.nowcoder.com/acm/contest/13#question
A.反蝴蝶效应
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; const int maxn=100005; int n; int a[maxn]; int main(){ cin>>n; int ans=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); ans=max(a[i]+i-1,ans); } cout<<ans<<endl; }
B.贝伦卡斯泰露
dfs暴力搜索,加几个优化
-
首先判断相同的数是否出现偶数次
-
记录每个数的总出现次数,若在某一个集合出现偶数次则跳出
-
若对于两个集合已经选择的数已经不是对应相等则跳出
#include<cstdio> #include<algorithm> #include<iostream> #include<vector> #include<cstring> using namespace std; vector<int> g1; vector<int> g2; int read(){ char ch; int x=0,f=1;ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int a[45],num[45],num1[45],num2[45]; int n; bool dfs(int x){ int z=min(g1.size(),g2.size()); if(x==n+1){ if(z!=n/2) return false; for(int i=0;i<n/2;i++){ if(g1[i]!=g2[i]) return false; } return true; } if(g1.size()>n/2||g2.size()>n/2) return false; for(int i=0;i<z;i++){ if(g1[i]!=g2[i]) return false; } int p=a[x]; if(num1[p]<num[p]/2){ num1[p]++; g1.push_back(p); if(dfs(x+1)) return true; num1[p]--; g1.pop_back(); } if(num2[p]<num[p]/2){ num2[p]++; g2.push_back(p); if(dfs(x+1)) return true; num2[p]--; g2.pop_back(); } return false; } int main(){ int t; scanf("%d",&t); while(t--){ memset(num,0,sizeof(num)); memset(num1,0,sizeof(num2)); memset(num2,0,sizeof(num2)); g1.clear(); g2.clear(); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); num[a[i]]++; } bool f=1; for(int i=1;i<=40;i++) if(num[a[i]]%2!=0){ printf("Furude Rika\n"); f=0; break; } if(!f) continue; if(dfs(1)) printf("Frederica Bernkastel\n"); else printf("Furude Rika\n"); } }
C 不会。。。
D.生物课程
首先只能有n-1条边,其次判断每个点所连接的点数,注意点较少时的特判
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; const int maxn=100005; int n,m; int num[maxn]; int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; if(x!=y){ num[x]++; num[y]++; } } if(m!=n-1){ cout<<"NotValid"<<endl; return 0; } if(n==2){ if(m==1&&num[1]==num[2]&&num[1]==1) cout<<"I"<<endl; return 0; } sort(num+1,num+1+n); if(num[1]==num[2]&&num[1]==1&&num[3]==num[n]&&num[3]==2){ cout<<"I"<<endl; return 0; } if(n>=5&&num[n]==4&&num[n-1]<num[n]&&num[1]==num[4]&&num[1]==1&&num[4]<num[5]){ cout<<"X"<<endl; return 0; } if(n>=4&&num[n]==3&&num[n-1]<num[n]&&num[1]==num[3]&&num[1]==1&&num[3]<num[4]){ cout<<"Y"<<endl; return 0; } cout<<"NotValid"<<endl; }
E.绝对半径2051
首先将相同的数的下标记录到同一个vector里,再二分答案,对于每个容器里的数判断是否满足
#include<cstdio> #include<algorithm> #include<iostream> #include<vector> using namespace std; const int maxn=100005; int z=0; struct P{ int x,i; }p[maxn]; int vis[maxn]; int n,k; vector<int> g[maxn]; int a[maxn]; int read(){ char ch; int x=0,f=1;ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } bool cmp(P a,P b){ if(a.x!=b.x) return a.x<b.x; return a.i<b.i; } bool C(int x){ for(int i=1;i<=z;i++) for(int j=0;j<g[i].size();j++){ if(g[i].size()-j<x) continue; int c=j+x-1; if(g[i][c]-g[i][j]+1>k+x) continue; return true; } return false; } int main(){ n=read(); k=read(); for(int i=1;i<=n;i++){ p[i].x=read(); a[i]=p[i].x; p[i].i=i; } if(n==0){ printf("0\n"); return 0; } sort(p+1,p+1+n,cmp); for(int i=1;i<=n;i++){ if(p[i].x!=p[i-1].x){ z++; //vis[p[i].i]=z; } vis[p[i].i]=z; g[z].push_back(p[i].i); // cout<<z<<p[i].i<<vis[p[i].i]<<-1<<endl; } int l=1,r=1e9+1; for(int i=1;i<=60;i++){ int mid=(l+r)/2; if(C(mid)) l=mid; else r=mid; } if(C(r)) printf("%d\n",r); else printf("%d\n",l); }
F.监视任务
先将所有的区间按照右端点进行排序,根据贪心的思想,每次用树状数组求(l[i],r[i])区间的和,若大于等于k[i],则不需操作,否则从r[i]开始向左进行操作,将不是1的全部改为1,直至区间和为k[i]
#include<cstdio> #include<algorithm> #include<iostream> #include<vector> #include<cstring> using namespace std; const int maxm=1000005; const int maxn=500005; int bit[maxn],vis[maxn]; int n,m; struct P{ int l,r,z; }p[maxm]; int sum(int x){ int s=0; while(x>0){ s+=bit[x]; x-=(x&-x); } return s; } void add(int x){ while(x<=n){ bit[x]+=1; x+=(x&-x); } } int read(){ char ch; int x=0,f=1;ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } bool cmp(P a,P b){ if(a.r!=b.r) return a.r<b.r; return a.l<b.l; } int main(){ n=read(); m=read(); for(int i=1;i<=m;i++){ p[i].l=read(); p[i].r=read(); p[i].z=read(); } sort(p+1,p+m+1,cmp); for(int i=1;i<=m;i++){ int z=sum(p[i].r)-sum(p[i].l-1); if(z>=p[i].z) continue; // cout<<z<<" "<<p[i].z<<-1<<endl; int k=p[i].z-z; for(int j=p[i].r;j>=p[i].l&&k>0;j--){ if(!vis[j]){ vis[j]=1; k--; add(j); } } } printf("%d\n",sum(n)); }