https://codeforces.com/contest/1560/problem/A
暴力打表
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
int f[30005],ans[30005],top=0;
int t,n;
int main()
{
ios
for(int i=1;i*3<=3000;i++)
{
f[i*3]=1;
}
for(int i=1;i<=3000;i++)
{
if(i%10==3)f[i]=1;
}
for(int i=1;i<=3000;i++)
{
if(f[i]==0)
ans[++top]=i;
}
cin>>t;
while(t--)
{
cin>>n;
cout<<ans[n]<<endl;
}
return 0;
}
https://codeforces.com/contest/1560/problem/B
给你两个数a,b,他们是一个环中相对的两个数,问你给定的c对应的数是什么
环中数的数量为(a-b)/2,那么分情况讨论c即可
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
int t,a,b,c;
void solve()
{
cin>>a>>b>>c;
if(a<b)swap(a,b);
int sum=(a-b)*2;
if((sum%2==1) && c==sum/2+1)
{
cout<<-1<<endl;
}
if(c>sum||sum<a)
{
cout<<-1<<endl;
return;
}
else if(c>ceil(sum*1.0/2))
{
cout<<c-(a-b)<<endl;
}
else
{
cout<<c+(a-b)<<endl;
}
}
int main()
{
ios
cin>>t;
while(t--)solve();
return 0;
}
https://codeforces.com/contest/1560/problem/C
给你这个表,问你k的x轴和y轴是多少
注意到斜线((1,1)(2,2)(3,3))中数为n^2-n,n为他在第几层。
我们对他取根号,取ceil(向上取整)得到他在第几层,
然后如果所求的数k大于n^2-n,就把x轴左移,反之把y轴上移即可。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
int n,t;
void solve()
{
cin>>n;
int k=ceil(sqrt(n));
int mid=k*k-(k-1);
int x=k,y=k;
//cout<<mid<<endl;
if(n>mid)
{
x=(k-(n-mid));
}
else if(n<mid)
{
y=(k-(mid-n));
}
cout<<y<<' '<<x<<endl;
}
int main()
{
ios
cin>>t;
while(t--)solve();
return 0;
}
https://codeforces.com/contest/1560/problem/D
给你一个n,你有两种操作
1.在这个数后面增加一个任意数
2.将整个数任意删除一位
问你至少要多少次操作,才能把n变成任意2的n次方。
这道题由于我们只能在他的后面加数,而可以随意删除,那就说明这个数一定是2的n次方的前缀的某个子序列。也就是说,n中一定含有2的n次方的某个前缀的所有数,而2的n次方不必含有n中的所有数。
我们可以先把两个数每位数提取出来,然后用双指针算法,如果两字符串匹配,则将两指针右移,如果不匹配,只将n的指针右移,最后匹配出最大的相同字串,需要修改的次数就是两串的长度减去共同序列的长度。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
int t;
ll pow2[600]={1};
ll check(ll x,ll y)
{
char a[6005],b[6005];
int topa=0,topb=0;
while(x)
{
a[++topa]=x%10;
x/=10;
}
while(y)
{
b[++topb]=y%10;
y/=10;
}
ll lena=topa,lenb=topb;
ll cnt=0;
while(topa>0&&topb>0)
{
if(a[topa]==b[topb])
{
topa--;topb--;
cnt++;
}
else
{
topa--;
}
}
return ((lena-cnt)+(lenb-cnt));
}
void solve()
{
ll n;
cin>>n;
ll minn=1e9+7;
for(int i=0;i<=63;i++)
{
minn=min(check(n,pow2[i]),minn);
}
cout<<minn<<endl;
}
int main()
{
ios
for(int i=1;i<=63;i++)
{
pow2[i]=pow2[i-1]*2;
}
cin>>t;
while(t--)solve();
return 0;
}
https://codeforces.com/contest/1560/problem/E
给你一个字符串A,问他是否能由一个字符串B删除其中的某一个字母然后添加到C的后面(C一开始与B相同),反复如此操作得到。
例如要得到 abacabaaacaac
我们可以由 abacaba 删除b 得到 aacaa
然后把 aacaa 加到 abacaba 后面 变成 abacabaaacaa
最后再把aacaa 删掉 a 得到 c
然后把 c 加到 abacabaaacaa 后面 变成 abacabaaacaac,得到原串。
要求输出字符串B,也就是abacaba 和 删除字母的顺序。
删除的顺序很好求,从后往前数出现的不同的字母就是。
而求子串呢,最暴力的思想是,把从开头开始的每一个字串(a,ab,aba,abac……)都当作字符串B尝试一遍上述操作。但这样时间复杂度太高。
我们发现,如果要得到字符串A,我们操作后的长度一定要与字符串A相同,那么我们可以先判断我们操作之后的长度是多少,如果长度和字符串A匹配,再进行暴力匹配尝试。这样就可以大大减少时间复杂度。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
const int N=5e5+55;
char str[N];
int check[1000],t;
char del[105]; int topd;
int ch[1005];
int checks(char anss[])//这里我发现直接用ans他会把ans直接修改掉。。但是代码已经写好了,所以我直接把真正的ans换了个名字,然后用ans代替后面的替换
{
char ans[N]={0};
strcpy(ans,anss);
int lena=strlen(ans);
int lend=strlen(del);
char tmp[N]={0};
strcpy(tmp,ans);
for(int i=0;i<lend;i++)
{
int lent=strlen(tmp);
for(int j=0;j<lent;j++)
{
if(tmp[j]=='*')continue;
if(tmp[j]==del[i])
{
tmp[j]='*';
}
else ans[lena++]=tmp[j];
}
}
//cout<<ans<<endl;
if(strcmp(str,ans)==0)return 1;
return 0;
}
void solve()
{
memset(check,0,sizeof(check));
memset(del,0,sizeof(del));
topd=0;
int times=0;
cin>>str;
int len=strlen(str);
for(int i=0;i<len;i++)
{
ch[str[i]-'a'+1]++;
}//计算各种字母个数
for(int i=len-1;i>=0;i--)
{
if(!check[str[i]-'a'])
{
check[str[i]-'a']=1;
del[topd++]=str[i];
// times++;
}
}
int turns[30];//turns存储的是一个字母出现了多少轮
int lendel=strlen(del);
reverse(del,del+lendel);//以后字符串再也不从1开始了。
for(int i=0;i<lendel;i++)
{
turns[del[i]-'a']=i+1;
}
int sum=0;//sum存储的是如果以这个为前缀,字符串应该有多长
char ans[N]={0};int topa=0;
//cout<<del<<endl;
for(int i=0;i<len;i++)
{
sum+=turns[str[i]-'a'];
//cout<<sum<<endl;
ans[topa++]=str[i];
if(sum==len)
{
cout<<ans<<' ';
cout<<del<<endl;
return;
}
}
cout<<-1<<endl;
}
int main()
{
ios
cin>>t;
while(t--)solve();
return 0;
}