Educational Codeforces Round 139 A-D
A. Extremely Round
题解:
输出1-n的数中,数位里面只有一个数字不为0的数的个数,观察到1,2,3...9,10,20,30...90,100,每位数中有9个这样的数,模拟即可
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6;
int a[N],b[N],n,m,x,y,z,t,k,q;
int ans,res;
string s;
vector<int>v;
map<int,int>mp;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
cin>>x;
if(x<=10)
{
cout<<x<<"\n";
continue;
}
y=x;
ans=0;
while(y>10)
{
y/=10;
ans+=9;
}
ans+=y;
cout<<ans<<"\n";
}
return 0;
}
B. Notepad#
题解:
易知,连续的两个字母定义为XY,如果有多个XY相同且不是XXX的情况出现,则为YES,否则NO
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6;
int a[N],b[N],n,m,x,y,z,t,k,q;
int ans,res;
string s;
vector<int>v;
map<int,int>mp;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
map<string,int>mp;
cin>>n;
cin>>s;
bool ok=true;
string ss="";
for(int i=2;i<=n-1;i++)
{
ss="";
ss+=s[i-1];
ss+=s[i];
if(mp[ss])
{
cout<<"YES"<<"\n";
ok=false;
break;
}
else
{
ss="";
ss+=s[i-2];
ss+=s[i-1];
mp[ss]++;
}
ss="";
}
if(ok)
cout<<"NO"<<"\n";
}
return 0;
}
C. Hamiltonian Wall
题解:
给你两行仅有BW组成的字符串,询问里面的所有B字符能否一笔画出来。
模拟即可,易知有三种情况是NO,
有B跟其他B断连;
在连续出现两行B的情况下,如果连续两行B的连续的列数为偶数,那么接下来接起来的B一定与一开始的B同行,即不同行的话为NO;
相同的,如果连续两行B的连续的列数为奇数,那么接下来接起来的B一定与一开始的B不同行,即同行为NO
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
int a[N],b[N],n,m,x,y,z,t,k,q;
int ans,res;
string s;
vector<int>v;
map<int,int>mp;
int ch[5][N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
cin >> n;
char xx;
for(int j=1; j<=2; j++)
{
for(int i=1; i<=n; i++)
{
cin >> xx;
if(xx == 'W') ch[j][i] = 0;
else ch[j][i] = 1;
}
}
ch[1][0] = 1;
ch[2][0] = 1;
ch[1][n + 1] = 1;
ch[2][n + 1] = 1;
int i=1;
bool ok=true;
while(i<=n)
{
int j = i;
while(ch[1][j] + ch[2][j] == 2 && j <= n)
j ++;
if(j == i)
{
if(ch[1][i] + ch[1][j + 1] == 2)
{
i ++;
continue;
}
else if(ch[2][i] + ch[2][j + 1] == 2)
{
i ++;
continue;
}
else
{
cout<<"NO"<<"\n";
ok=false;
break;
}
}
if((j-i)%2==1)
{
bool xxx=!((ch[1][i - 1] == 1 && ch[2][j] == 1) ||(ch[2][i - 1] == 1 && ch[1][j] == 1));
if(xxx)
{
cout<<"NO"<<"\n";
ok=false;
break;
}
}
else
{
bool yyy=!((ch[1][i - 1] == 1 && ch[1][j] == 1) ||(ch[2][i - 1] == 1 && ch[2][j] == 1));
if(yyy)
{
cout<<"NO"<<"\n";
ok=false;
break;
}
}
i = j;
}
if(ok)cout<<"YES"<<"\n";
}
return 0;
}
D. Lucky Chains
题解:
题意是给你两个数x和y,求gcd(x+k,y+k)!=1式子的k的最小值,若式子一直不成立则输出-1
令gcd(x+k,y+k)=d,
有式子:①x+k=a*d ②y+k=b*d
②-①:y-x=(b-a)*d 则知道了 d | (y-x) ,即d为 (y-x)的因数
再着眼于gcd(x+k,y+k)=d ,推出k=d-x%d,欲求k的最小值,
下证只需要枚举(y-x)的质因数即可,
证明d在(y-x)的质因数中枚举比d在(y-x)的非质因数中枚举更优:
否则,令d为(y-x)的非质因数,由整数的唯一分解定理,d=,
不妨令d=p1*p2,则令 k1=(p1*p2)-X%(p1*p2) , k2=p1-X%p1.
有,推出函数
当p>=X时,该函数递增,当0<p<x时,,该函数也递增
综上,又由于p1<=p1*p2,则枚举质因数更优
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int n,x,y,a[N],b[N];
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
get_primes(1e6);
while(T--)
{
cin>>x>>y;
if(__gcd(x,y)!=1)
{
cout<<0<<"\n";
continue;
}
if(x==y-1)
{
cout<<-1<<"\n";
continue;
}
int m=y-x;
vector<int>v;
for(int i=0;primes[i]*primes[i]<=m&&i<cnt;i++)
{
int j=primes[i];
if(m%j==0)
{
while(m%j==0)m/=j;
v.push_back(j);
}
}
if(m>1)v.push_back(m);
int ans=y-x;
for(auto res:v)
{
ans=min(ans,((x-1)/res+1)*res-x);
}
cout<<ans<<"\n";
}
return 0;
}