题目链接:
https://codeforces.com/contest/1496
思路:
(1).对k的大小进行考虑。如果k=0,直接YES;如果2*k+1>n,直接NO。
(2)字符串是以ABA形式存在,所以判断字符串前半段与后半段是否对称。并且,对称的长度,num>=k。
AC代码:
#include
using namespace std;
char s[110];
int n,k,t;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
cin>>s;
// cout<
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
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
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
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;
}