Codeforces Round #739 (Div. 3)

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值