CodeForces - 1238A
给出x,y(x>y),问x-y是否可以用一个素数的k(k>0)倍表示
#include <bits/stdc++.h>
using namespace std;
int main(){
int t;
cin >> t;
while(t--)
{
long long x,y,z;
cin>>x>>y;
z=x-y;
if(z<=1) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
很简单的一道题,但我没有一开始就看到他的本质,想的不透彻,正确的应该是:任意数都可以分解为若干个素数之积,如n=(k1的m1次幂)(k2的m2次幂)(k3的m3次幂),则可化为 n = (k1的m1-1次幂) * (k2的m2次幂) * (k3的m3次幂)* k1 ,就是 k1 的 m1-1次幂)(k2的m2次幂)(k3的m3次幂)倍的 k1 。
CodeForces - 1238C
在一个高度为h的山上每个高度都有台阶, 其中有n个台阶显示出来,其他都是闭上的,只有显示的能跳,但每跳到一个台阶下一个高度(不一定是不显示的)的台阶状态就会变换,跳到比原来大于2个距离就会死,每次魔法可以改变某个台阶的状态,问不死跳到底最少需要多少次魔法
1.如果x-2高度处有挡板,那么我们在x处,x和x-1高度处的挡板都收起,小人恰好落在x-2高度处的挡板
2.如果x-2高度处没有挡板,那很显然x和x-1处的挡板收起后就没了,所以使用魔法让x-1高度处的挡板收起来,然后进行下一步的时候x-1高度处的挡板恰好伸出,落上去
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int a[200010];
int main()
{
int t;
cin>>t;
while(t--)
{
int h,n;
cin>>h>>n;
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
a[n]=0;
int ans=0;
for(int i=1;i<n;i++)
{
if(a[i+1]+1==a[i])
i++;
else
ans++;
}
printf("%d\n",ans);
}
return 0;
}
每次的 i 是x+1,我所在的位置是 x 即a [ i-1 ],题目不难,但是我没看懂……
CodeForces - 1238D
good string定义:给定一个字符串,随意取给出字符串的连续子串,如果这个字符串的每一个字母都能找到包括该字母的连续回文子串,则这个字符串是good的。现在给出一个子串,问它的所有连续子串中有几个是good的。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n;
cin>>n;
string s;
cin>>s;
int sa=0,sb=0;
int fa=0,fb=0;
long long ans=0;
for(int i=0;i<n;i++)
{
if(s[i]=='A')
{
sa++;
fa = 1;
if(sa==1&&fb) ans+=sb;
if(sa>1&&fb) ans++;
sb=0;
}
else
{
sb++;
fb = 1;
if(sb==1&&fa) ans+=sa;
if(sb>1&&fa) ans++;
sa=0;
}
}
cout<<n*(n-1)/2-ans<<endl;
return 0;
}
又被题目卡了好久,这题需注意的一个点是虽然 n 是int 范围内的,但n*(n-1)/2超过了int ,所以需要定义 n 为long long,这样n*(n-1)/2才能得到正确的结果
CodeForces - 1238E
给出由最多 m 种字符构成的长度为 l 的字符串。定义两个相邻字符的代价之差是两个字符对应位置的绝对值,求这m种字符的一种排列方式,使得总的代价之和最小并得出最小代价。
#include<bits/stdc++.h>
using namespace std;
int n,m,g[21][21],f[1048576];
char s[100010];
int main(){
scanf("%d%d%s",&n,&m,s+1);
for(int i=2;i<=n;++i)
g[s[i-1]-'a'][s[i]-'a']++,g[s[i]-'a'][s[i-1]-'a']++;
for(int i=1,c;i<(1<<m);++i){
c=0;
f[i]=0x3f3f3f3f;
for(int j=0;j<m;++j)
for(int k=j+1;k<m;++k)
if((i>>j&1)^(i>>k&1))
c+=g[j][k];
for(int j=0;j<m;++j)
if(i>>j&1)
f[i]=min(f[i],f[i^(1<<j)]+c);
}
printf("%d\n",f[(1<<m)-1]);
}
CodeForces - 1238F
题解