Educational Codeforces Round 81 (Rated for Div. 2)(训练)
打卡题,只要让位数尽量多(即让1的个数尽量多)
代码:
#include<bits/stdc++.h>
#define ll long long
#define maxn 1e5+9
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int main()
{
int t,n;
cin>>t;
while(t--){
cin>>n;
if(n%2==0){
for(int i=1;i<=n/2;i++){
cout<<1;
}
}else{
cout<<7;
for(int i=1;i<=(n-3)/2;i++){
cout<<1;
}
}
cout<<endl;
}
return 0;
}
题目大意:给你一个字符串s(只由0和1组成),字符串t=sssss.... ,给你一个数x,求在字符串t中,有多少个前缀子串满足d0-d1(0的数量减1的数量)=x,如果没有确切数量,则输出-1。
思路:先求出在s中,每个位置的d0-d1的值,设整个字符串s的d=xx。
(1)如果xx=0,即在s中0和1的个数相等,如果在s中任意一个前缀的d0-d1=x时,就有无数个解。
(2)我们设在字符串s中某一位置的d0-d1=p,若要满足条件,即(x-p)%xx=0,则sum++。
(3)如果x=0时,空串也是符合的,即当x=0时,sum++。
代码:
#include<bits/stdc++.h>
#define ll long long
#define maxn 1e5+9
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
string s;
int p[200005];
int main()
{
int t;
ll n,x;
cin>>t;
while(t--){
int num=0;
cin>>n>>x;
cin>>s;
ll xx=0;
for(int i=0;i<n;i++){
if(s[i]=='0')xx++;
else xx--;
}
if(x==0)num++;
if(xx==0){
int ss=0,k=0;
for(int i=0;i<n;i++){
if(s[i]=='0')ss++;
else ss--;
if(ss==x){
k=1;
break;
}
}
if(k){
num=-1;
}
}else{
int p=0;
for(int i=0;i<n;i++){
if(s[i]=='0')p++;
else p--;
if((x-p)%xx==0&&(x-p)/xx>=0){
num++;
}
}
}
cout<<num<<endl;
}
return 0;
}
题目大意:给你两个字符串s,t,你需要通过将s的子串一次次按顺序连接,变成t,问最少需要几步。
思路:用vector表示每个字母在s中的位置,再通过二分找s的子串与t中所需要的子串(让子串的位置尽可能在前面),并且让子串尽可能长(upper_bound的使用,即用来找最前面的符合条件的)。
代码:
#include<bits/stdc++.h>
#define ll long long
#define maxn 1e5+9
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
string s,t;
vector<int>v[30];
int num[30];
int main()
{
int T;
cin>>T;
while(T--){
cin>>s;
cin>>t;
for(int i=1;i<=28;i++){
v[i].clear();
num[i]=0;
}
for(int i=0;i<s.length();i++){
v[s[i]-'a'+1].push_back(i);
++num[s[i]-'a'+1];
}
int step=0,kk=1,p=-1;
for(int i=0;i<t.length();i++){
if(num[t[i]-'a'+1]==0){
kk=0;
goto end;
}else if(p>=v[t[i]-'a'+1][num[t[i]-'a'+1]-1]){
step++;
p=v[t[i]-'a'+1][0];
}else{
int op=t[i]-'a'+1;
p=v[op][upper_bound(v[op].begin(),v[op].end(),p)-v[op].begin()];
}
}
end:;
if(kk==0){
cout<<"-1"<<endl;
}else{
cout<<step+1<<endl;
}
}
return 0;
}
题目大意:给你a,m,求0<=x<m,有几个x满足 gcd(a,m)=gcd(a+x,m)。
解题思路:
代码:
#include<bits/stdc++.h>
#define ll long long
#define maxn 1e5+5
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
ll eular(ll n)
{
ll ans = n;
for(ll i=2; i*i <= n; ++i)
{
if(n%i == 0)
{
ans = ans/i*(i-1);
while(n%i == 0)
n/=i;
}
}
if(n > 1) ans = ans/n*(n-1);
return ans;
}
int main()
{
int t;
ll a,m;
cin>>t;
while(t--){
cin>>a>>m;
ll d=__gcd(a,m);
cout<<eular(m/d)<<endl;
}
return 0;
}
越自律,越自由