栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

1400——507B、1370C、1363B、1324D、1365C、1374D

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

1400——507B、1370C、1363B、1324D、1365C、1374D

今天是2021.10.1,国庆节。祝福伟大的祖国。
上午刷了两道,下午刷了一道,晚上刷了三道。


507.B. Amr and Pins (思维) 题意:

一个圆形,可沿边缘的一点任意角度旋转。问最少旋转几次,能将圆心从(a1,a2)旋转至(b1,b2)。

思考:

圆心在(x,y)点的圆,圆心可以旋转至2r范围内的任意一点。
所以将沿目标圆心和当前圆心的连线旋转,每次走2r。就是看2r的多少倍能够不小于两点间的距离。

注意int相乘加ll。

Code:
const int N = 200010, mod = 1e9+7;
int T, n, m;

int main(){
	int r,a1,a2,b1,b2;
	cin>>r>>a1>>a2>>b1>>b2;
	
	double dis=(ll)(a1-b1)*(a1-b1)+(ll)(a2-b2)*(a2-b2); //int类型相乘加ll 
	
	int cnt=0;
	double t=0;
	while(t*t 

1370.C. Number Game (博弈论) 题意:

给出一个数n,两个人轮流操作,不能操作者败。
操作1:将n除以一个不为1的奇因数(包括其本身);
操作2:将大于1的n减1。
A先手,两者操作都最优,问最终谁能胜?

思考:

如果n是奇数,那么直接除以其本身,所得为1,B无法再操作,A胜;

否则n为偶数:

  • 若n没有奇因子,即n为2^x次方(特判n=2),那A只能进行1操作,将n变为奇数,B胜;
  • 否则,n含奇因子:
    因为 奇数*奇数=奇数,所以可以一次将n的所有奇因子都拿完。
    1、如果去掉奇因子后,n变成2^x,即若n%4=0,那么A胜;
    2、去掉奇因子,n不能变成2^x,即n变成2,n=2*p(p为奇数):
    如果p为质数的话,B胜;
    但是如果p不为质数,那么p就可以分解为 质数p' * 奇数,把奇数拿去,A胜。
Code:
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];

bool prim(int n)
{
	if(n==1||n==0) return 0;
	
	for(int i=2;i<=n/i;i++){
		if(n%i==0) return 0;
	}
	return 1;
}

int main(){
	cin>>T;
	while(T--)
	{
		cin>>n;
		
		if(n%2||n==2||n==1){
			if(n==1) cout<<"FastestFingern";
			else cout<<"Ashishgupn";
			continue;
		}
		
		int t=1,flag=0;
		for(int i=1;i<=31;i++){
			t*=2;
			if(t==n) flag=1;
			if(t>n) break;
		}
		
		if(flag) cout<<"FastestFingern";
		else{
			if(n%4==0) cout<<"Ashishgupn";
			else{
				if(prim(n/2)) cout<<"FastestFingern";
				else cout<<"Ashishgupn";
			}
		}
	}
	
	return 0;
}

1363.B. Subsequence Hate (思维,前缀和) 题意:

给出一个01串,经过若干次01转换后,要求最终的01串不含有如下子序列:010,101。
求最少的转换次数。

思考:

不要去想着如何替换成目标序列,而是从最终的序列形式出发:
如果最终的01串不含有010,101这样的子序列,那么最终的序列形式一定是这样的:00001111…或111110000…或111111…或00000…。
于是题目就完全转化了!
就是把原来的01串转化成这样的01串,求最小的操作次数。

前缀和维护当前位置前面1的个数,遍历所有位置就行了。

Code:
const int N = 200010, mod = 1e9+7;
int T, n, m;
string a;
int s[N];

int main(){
	cin>>T;
	getline(cin,a);
	while(T--)
	{
		getline(cin,a);
		
		n=a.size();
		for(int i=1;i<=n;i++)
		{
			s[i]=s[i-1];
			if(a[i-1]=='1') s[i]++;
		}
		
		int ans=1e9;
		for(int i=0;i<=n;i++)
		{
			ans=min(ans,s[i]+n-i-(s[n]-s[i]));
			ans=min(ans,i-s[i]+s[n]-s[i]);
		}
		cout< 

1324.D. Pair of Topics (思维,二分) 题意:

给出长度为n的两个序列 a , b a,b a,b,问有多少对 i , j i,j i,j,满足 i < j i b i + b j ai+aj>bi+bj ai+aj>bi+bj ?

思考:

a i + a j > b i + b j ai + aj > bi + bj ai+aj>bi+bj
→ a i − b i + a j − b j > 0 → ai-bi + aj-bj > 0 →ai−bi+aj−bj>0

将两个序列合并成一个: c i = a i − b i ci = ai - bi ci=ai−bi,那么题目就转化为:
有多少对 i , j i,j i,j,满足 i < j i 0 ci + cj >0 ci+cj>0 ?

先将c数组从小到大排序,遍历每个位置,二分找到第一个满足的位置,那么此位置后面的所有位置都满足了,ans累加后面的位置数。

Code:
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];

int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	for(int i=1;i<=n;i++)
	{
		int x;cin>>x;
		a[i]-=x;
	}
	
	sort(a+1,a+n+1);
	a[n+1]=1e9;
	
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		int l=i+1,r=n+1;
		while(l>1;
			if(a[mid]+a[i]>0) r=mid;
			else l=mid+1;
		}
		if(l==n+1) continue;
		ans+=n-l+1;
	}
	cout< 

1365.C. Rotation Matching (思维) 题意:

给出长度为n的两个n的全排列,可以将两个序列像齿轮一样左右转动任意位置。问最多能使多少位置上下相同?

思考:

序列长度n<2e5,暴力做法不可行。

我们可以只转动下面的序列,使之与上面的序列匹配。

记录下a序列中的每个数在b序列中的位置。遍历计算b中的所有位置要向右转动转到其对应位置所需要的转动次数。
所有转动次数中出现最多的出现次数就是最大匹配数。

Code:
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int f[N];

int main(){
	Ios;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	for(int i=1;i<=n;i++){
		int x;cin>>x;
		mp[x]=i;
	}
	
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		a[i]=mp[a[i]];
		
		f[(i-a[i]+n)%n]++;
		ans=max(ans,f[(i-a[i]+n)%n]);
	}
	cout< 

1374.D. Zero Remainder Array (思维) 题意:

给出长度为n的序列,一个数x(初始为0),可以执行以下操作:
1.选择一个位置i,将 ai 加上 x,同时 x++(每个位置最多执行一次该操作);
2.只是将x++。

给出整数k,问最少执行多少次操作,能够使得序列a中的所有元素都是k的倍数?

思考:

无论执行那种操作,x都会++。
因为操作1每个元素最多只能执行一次,而x始终在增加,最终要变成k的倍数,所以如果有与最近的倍数差值相等的元素,需要变成下一个倍数。

所需要的最大的x就是最终需要的操作数。

注意:
因为有多组数据,所以每次的map需要初始化。如果用unordered_map的话,建立的时候太耗时了,就T掉了。而map的建立所用的时间较短些。
所以如果有多组测试数据需要初始化map的题,都用map较好。

Code:
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];

signed main(){
	Ios;
	cin>>T;
	while(T--)
	{
		int k;
		cin>>n>>k;
		
		map f;
		ll ans=0;bool flag=0;
		for(int i=1;i<=n;i++)
		{
			int x;cin>>x;
			if(x%k==0) continue;
			flag=1;
			int p=k-x%k;
			
			if(f[p]) f[p]+=k;
			else f[p]=p;
			
			ans=max(ans,f[p]);
		}
		cout< 

这几个题都有一个特点,就是将原本的题意转化,挖掘深层的含义。
明天加油!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号