首页 > 其他分享 >Codeforces Round #847 (Div. 3) ABCDE

Codeforces Round #847 (Div. 3) ABCDE

时间:2023-01-29 15:56:36浏览次数:84  
标签:847 map int res void ABCDE cin solve Div

url:Dashboard - Codeforces Round #847 (Div. 3) - Codeforces

A. Polycarp and the Day of Pi

题意:

判断给的字符串前多少位跟PI一样

思路:

打个表,然后遍历一下即可,遇到不是的就退出

代码:

string op = "314159265358979323846264338327950288419716939937510";
 
void solve()
{
	string s1;
	cin >> s1;
	for(int i = 0;i < s1.size();i++)
	{
		if(s1[i] != op[i])
		{
			cout << i << endl;
			return;
		}
	}
	cout << s1.size() << endl;
}

总结:

水题,不总结(

B. Taisia and Dice

题意:

给n个骰子,和n个骰子的点数之和和去掉最大点数的点数之和

思路:

先可以求出最大的骰子点数maxn

然后用剩下的点数去分配给n - 1个骰子,使得点数为[1,maxn]

最开始想的是弄个平均值啥的

后来一看范围就直接暴力好了,就循环一个一个放,这样保证了一定平均值是最小的

但是今天写题解时想了想,居然把昨天那种平均值方法写出来了

就是先求出$x = res / (n - 1)$和$y = res % (n - 1)$

然后输出前$n - 1 - y$个$x$

再输出前$y$个$x + 1$

最后输出$maxn$

代码1:

void solve()
{
	int sum,res;
	cin >> n >> sum >> res;
	vector<int> a(n + 1);
	int maxn = sum - res;
	for(int i = 1;i <= n - 1;i++)
	{
		if(res > 0) a[i]++;
		else break;
		res--;
		if(i == n - 1) i = 0;
	}
	for(int i = 1;i <= n - 1;i++) cout << a[i] << " ";
	cout << maxn << endl;
}

代码2:

void solve()
{
	int sum,res;
	cin >> n >> sum >> res;
	vector<int> a(n + 1);
	int maxn = sum - res;
	int x = res / (n - 1);
	int y = res % (n - 1);
	// cout << x << " " << y << endl;
	for(int i = 1;i <= n - 1 - y;i++) cout << x << " ";
	for(int i = 1;i <= y;i++) cout << x + 1 << " ";
	cout << maxn << endl;
}

C. Premutation

题意:

给n个n - 1长度的排列

每个排列都为一个原始排列去掉了一个数所成的,保证n个排列去掉的数不相同

思路:

主要是读题就读了很久,大概知道什么意思后感觉就看出来规律

主要是顺序是乱的,所以看起来很难受

后来想一想,

每个位置都少出现一次

那只要看第一个位置,必然会有一个不同的

找到不同的那个位置,然后输出其余n - 1个相同的那个数

再输出剩下的n - 1个位置的数即可

但是这种过程中想用用全部异或以来那个技巧

然后才发现那个是用来找所有数都出现偶数次,只有一个数出现奇数次才能用的

这个时候用map老老实实暴力就好了

别想着花里胡哨的(

代码:

void solve()
{
	cin >> n;
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= n - 1;j++)
			cin >> a[i][j];
	map<int,int> mp;
	for(int i = 1;i <= n;i++) mp[a[i][1]]++;
	int q1,q2,idx;
	for(auto it : mp)
	{
		if(it.se == 1) q1 = it.fi;
		else q2 = it.fi;
	}
	for(int i = 1;i <= n;i++)
	{
		if(a[i][1] == q1)
		{
			idx = i;
			break;
		}
	}
	cout << q2 << " ";
	for(int i = 1;i <= n - 1;i++) cout << a[idx][i] << " ";
	cout << endl;
}

总结:

别想着玩花的技巧

就算多跑个循环,多开点变量,都不会有事(

能过就行(

D. Matryoshkas

题意:

给n个数,问最少能凑成几个集合

思路:

贪心凑,排序后从最小的开始,然后找这个数+1的数

直接双重循环 + 标记数组会TLE

这时候需要用map来优化一波

还是先排序,不过先把每个值装到map里

还是按照a[i]的1到n来遍历

不过每次先检查map[a[i]]是否为空

然后再将循环减去a[i]递增的值

这样就省去了开标记数组的时间和一部到位直接到下一个值

而不是一堆continue来占用时间

暴力代码:

void solve()
{
	int ans = 0;
	cin >> n;
	vector<int> a(n + 1),st(n + 1,0);
	for(int i = 1;i <= n;i++) cin >> a[i];
	sort(all(a));
	for(int i = 1;i <= n;i++)
	{
		int x = a[i] + 1;
		if(st[i]) continue;
		for(int j = i + 1;j <= n;j++)
		{
			if(st[j]) continue;
			if(a[j] == x)
			{
				st[j] = 1;
				x++;
			}
		}
		ans++;
	}
	cout << ans << endl;
}

优化代码:

void solve()
{
	int ans = 0;
	map<int,int> mp;
	cin >> n;
	vector<int> a(n + 1);
	for(int i = 1;i <= n;i++) cin >> a[i],mp[a[i]]++;
	sort(all(a));
	for(int i = 1;i <= n;i++)
	{
		if(mp[a[i]])
		{
			int idx = a[i];
			while(mp[idx])
			{
				mp[idx]--;
				idx++;
			}
			// cout << idx << endl;
			ans++;
		}
	}
	cout << ans << endl;
}

总结:

如果暴力过程中出现了一堆continue的情况

这时候就可以用map来进行优化

E. Vlad and a Pair of Numbers

题意:

给一个数n,要你求两个数a和b,使得$a 异或 b == n$而且$(a + b) / 2 == n$

思路:

考虑位运算

$(a + b) / 2$要求$a + b$肯定要是个偶数

所以a和b要么同为奇数,要么同为偶数

但是n为奇数的话二进制形式最后一位为1

显然矛盾了,所以n只能为偶数

然后看公式,就是要求两个数相加后向右移一位等于这两个数异或起来的值

首先构造$a 异或 b == n$

如果n的位置上为1,a,b则可以放1 0或者0 1

如果n的位置上为0,a,b则可以放1 1或者0 0

然后再构造$(a + b) / 2 == n$

其实就是二进制形式相加进位后我们希望结果为n向左移一位

这样再/2向右移一位,这样刚好结果为n

那就变成了如何安排a和b的二进制形式使得结果为n向左移一位

实际向左移一位就是所有1进位即可

要想要所有1进位,安排如下:
1变成1 0

1后面的一个0变成 1 1

其余0变成0 0

这样即可保证所有1进位

另外不能有连续的1出现在n中

因为连续的1的话,要么就留在那里不动,要么这几位都变成0

不能保证向左移一位

代码:

void solve()
{
	cin >> n;
	if(n&1)
	{
		cout << -1 << endl;
		return;
	}
	bitset<32> op(n),a(0),b(0);
	int x = 0,y = 0;
	bool flag = 0;
	for(int i = 31;i >= 0;i--)
	{
		if((i != 0)&&(op[i] == 1)&&op[i - 1] == 1)
		{
			cout << -1 << endl;
			return;
		}
		if(op[i] == 1)
		{
			a[i] = 1;
			b[i] = 0;
			flag = 1;
		}
		else if(flag)
		{
			a[i] = 1;
			b[i] = 1;
			flag = 0;
		}
		else
		{
			a[i] = 0;
			b[i] = 0;
		}
		if(a[i]) x += 1 << i;
		if(b[i]) y += 1 << i;
	}
	cout << x << " " << y << endl;
}

总结:

看到^和数据范围给的是2的次方的时候考虑位运算

从公式入手,*2代表左移,/2代表右移

奇数和偶数都举一个例子

   

标签:847,map,int,res,void,ABCDE,cin,solve,Div
From: https://www.cnblogs.com/rickly233/p/17072887.html

相关文章

  • Codeforces Round #801 (Div. 2) and EPIC Institute of Technology Round A - D
    题目链接A#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;#defineintlonglongconstintN=1e3+10;intn,m;intg[N][N......
  • 定位的div环形圆形排列
    要实现一个类似于下图的效果,十个标签从中间随机出现的动画效果,若没有十个则按定义位置出现1.将十个标签都固定在中心位置,通过class,并且动态生成标签颜色<div......
  • Codeforces Round #847 F
    F.TimofeyandBlack-WhiteTree题链因为是一棵树的形式我们不妨考虑dpdp[u]表示u节点子树内黑点离u的最近距离我们每添加一个点当然会更新他及他链上面父亲的dp值......
  • Codeforces Round #816 (Div. 2)
    D.2+doors要让字典序最小就要让每个数字在满足条件的同时都尽可能的小并且排在前面的数字变小的优先级要比排在后面的数字的优先级更大。\[\begin{aligned}1\operator......
  • Codeforces Round #847 (Div. 3)
    E.VladandaPairofNumbers题目抽象为给\(n\)\((1\len\le2^{29})\),求\(x\)满足\((n-x)\oplus(n+x)=n\),输出\(n-x\)和\(n+x\)。显然\(n\)为奇数肯定不行......
  • CF 1790E. Vlad and a Pair of Numbers_Codeforces Round #847 (Div. 3)
    给出整数x,求一对整数(a,b),满足:\(a\bigoplusb=x\),\(\frac{a+b}{2}=x\)(\(\frac{a+b}{2}\)不四舍五入,也就是\(2\mida+b\))如果不存在这样的(a,b)输出-1分析:如果x的最......
  • # CF#847 (Div. 3)ABCDE题解
    CodeforcesRound#847(DFiv.3)APolycarpandtheDayofPiProblem-A-Codeforces题目描述OnMarch14,thedayofthenumber$\pi$iscelebratedallov......
  • Codeforces Round #846 (Div. 2)
    题目链接D题意给定一个数字n,我们需要通过一系列的操作去猜测这个数字。初始的时候会给我们一个cnt,表示二进制下数字n有多少个1.每次我们可以给出一个t,然后另n减去t,系统......
  • Codeforces Round #601 (Div. 2) A-E
    比赛链接A题意给两个数字\(a,b\),每次操作可以使\(a\)加上\(+1,+2,+5,-1,-2,-5\)中的一个数,求最少多少次操作可以将\(a\)变成\(b\)。题解知识点:贪心。可以......
  • 1.27 vp Codeforces Round #845 (Div. 2) and ByteRace 2023
    A-EverybodyLikesGoodArrays!题意(构造)给出序列a,需要使a中元素以相邻元素奇偶性不同排列,你可以进行若干操作:将一对相邻奇偶性相同的元素相乘问最少需要多少次操作......