赞
踩
题目链接:
https://codeforces.com/contest/1496
思路:
(1).对k的大小进行考虑。如果k=0,直接YES;如果2*k+1>n,直接NO。
(2)字符串是以ABA形式存在,所以判断字符串前半段与后半段是否对称。并且,对称的长度,num>=k。
AC代码:
#include<bits/stdc++.h> using namespace std; char s[110]; int n,k,t; int main() { cin>>t; while(t--) { cin>>n>>k; cin>>s; // cout<<s<<endl; int flag=0; int num=0; for(int i=0;i<n/2;i++) { if(s[i]==s[n-1-i]) num++; else { flag=-1; break; } } // printf("flag==%d\n",flag); if(num>=k&&!(n<2*k+1)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
思路:
1.如果k=0,直接输出n.注意:这里a数组中的元素每个都是不同的(题目已经说了,我写的时候就没看到,导致一直WA)
2.如果a数组是以0.1.2.3.4连续的形式,可以手算一下,每一次的计算,都会产生新的最大值,就是会接着后面一个数继续增加1。所以,这种情况直接输出n+k。
3.如果上面两种都不满足,计算一下新的数,如果新的数在a数组中出现过,那么每次的操作都是这个数生成,答案不变,输出n。如果没有出现过,输出n+1。
ps:自己写的时候把四舍五入写错了。。。太粗心了//
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; ll mp[N]; ll a[N]; ll t,n,k,mex,maxv; int main() { cin>>t; while(t--) { ll ans=0; cin>>n>>k; maxv=-1; memset(mp,0,sizeof(mp)); for(int i=0;i<n;i++) { cin>>a[i]; } if(k==0) { cout<<n<<endl; continue; } int flag=0; sort(a,a+n); for(int i=0;i<=n-1;i++) { if(a[i]!=i) { mex=i; flag=-1; break; } } if(flag==0) { n+=k; cout<<n<<endl; continue; } else { maxv=a[n-1]; // printf("mex===%d max===%d\n",mex,maxv); float h=(mex+maxv)*1.0/2; //printf("h==%d\n",h); int p= int(h+0.5); // printf("p===%d\n",p); flag=0; for(int i=0;i<n;i++) { if(a[i]==p) { flag=-1; } } if(flag==-1) { cout<<n<<endl; } else { cout<<n+1<<endl; } } } return 0; }
思路:随便找几个数算一下,例如(5,0)(1,0)(0,1)(0,2),就可以发现,X上离原点近的和Y上离原点近的相连,这样得出来的路程最短。
所以两个数组排序一下,然后累加就ok。
ps:输入数组的时候不能用 cin 不然会超时,又吃了这个亏。。。
AC代码
:
//C. Diamond Miner #include<bits/stdc++.h> using namespace std; const int N=1e5+10; typedef long long ll; double x[N],y[N]; int n,t,cnt1,cnt2; double a,b; int main() { cin>>t; while(t--) { cnt1=0; cnt2=0; cin>>n; for(int i=1;i<=2*n;i++) { scanf("%lf%lf",&a,&b); if(a==0) { y[++cnt1]=abs(b); } else { x[++cnt2]=abs(a); } } sort(y+1,y+cnt1+1); sort(x+1,x+cnt2+1); double ans,res; ans=0,res=0; for(int i=1;i<=n;i++) { ans+=sqrt(x[i]*x[i]+y[i]*y[i]); } printf("%.10lf\n",ans); } return 0; }
D自己想没有想出来。这里贴一下别的大佬的思路
:
如果有最长路,那么最长路的个数不能>1。因为如果大于1,A先手,B走另外一条就可以赢。
然后我们就只要判断,最长路的点的左边与右边是否相等,如果相等并且是奇数,那么A赢。
如果不相等,后手的B只要构造,缩小长度变成偶数就可以赢。就是0
AC代码:
ps:这里顺便学了一下,用二维数组动态的存每个点所在升序序列和降序序列的长度。
//D. Let's Go Hiking #include<bits/stdc++.h> using namespace std; const int N=1e5+10; typedef long long ll ; ll n; ll arr[N]; ll dp[N][2]; map<ll,ll> cnt1; map<ll,ll> cnt2; set<int> st; int main() { cin>>n; for(int i = 1;i<=n;++i) { scanf("%d",&arr[i]); } for(int i = 1;i<=n;++i) { if(i==1) dp[i][0] = 1; else { if(arr[i]>arr[i-1]) dp[i][0] = dp[i-1][0] + 1; else dp[i][0] = 1; } } for(int i = n;i>=1;--i) { if(i==n) dp[i][1] = 1; else { if(arr[i]>arr[i+1]) dp[i][1] = dp[i+1][1] + 1; else dp[i][1] = 1; } } ll maxx=0; for(int i=1;i<=n;i++) { maxx=max(maxx,max(dp[i][0],dp[i][1])); } for(int i=1;i<=n;i++) { if(dp[i][0]==maxx||dp[i][1]==maxx) st.insert(i); } if(st.size()>1) { cout<<"0"<<endl; return 0; } int xb=*st.begin(); if((dp[xb][0]==dp[xb][1])&&(dp[xb][0]%2==1)) { cout<<"1"<<endl; return 0; } cout<<"0"<<endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。