Codeforces Round #547 (Div. 3)(A,C两题)【数学,思维】

A Game 23

题目大意:给你两个数字,一个数字只能通过*2 和*3来得到另一个数字,问需要多少不才能从一个数字变成另一个数字。

大致思路:如果数字a能够变成数字b,则数字b一定可以整除数字a,然后再用他们的商先除2,在除3最后统计一共除了多少下,就是最后的答案了。

#include 

using namespace std;

long long a,b;

int count(long long &x){
	int cnt = 0;
	while(x % 2 == 0) {x /= 2; cnt++;}
	while(x % 3 == 0) {x /= 3; cnt++;}
	if(x != 1) cnt = -1;
	return cnt;
}


int main() {
	cin >> a >> b;
	if(b % a == 0){
		long long c = b / a;
		cout << count(c) << endl;
	} else puts("-1");
	return 0;
}

C. Polycarp Restores Permutation

题目大意:我们知道了一组数字的前两项之差,现在要你求出这组数字。并且这组数字按照1~n排列并且不重复

大致思路:我们假设这组数据一共有4组,相邻两项的差分别为x,y,z。则

a[2] - a[1] = x;
a[3] - a[2] = y;
a[4] - a[3] = z;
a[4] - a[1] = z + x + y;
a[3] - a[1] = y + x;
a[2] - a[1] = x;
a[4] + a[3] + a[2] + a[1] = 2 * y + 3 * x + z + 4 * a[1]
n * (n + 1) / 2 = 3 * x + 2 * y + z + 4 * a[1]

由此我们可以求出来a[1],然后整个数组都可以求出来,同时我们在把这组数据存入set里看看有没有重复的数字就行了。

#include 

using namespace std;

const int MAXN = 2e6 + 10;
typedef long long LL;
LL n,p[MAXN],q[MAXN];
int vis[MAXN];
set se;

int main(int argc, char const *argv[])
{
	cin >> n;
	bool flag = false;
	cin >> q[1];
	for(LL i = 2; i <= n - 1; i++) {
		cin >> q[i];
	}
	LL sum = 0;
	for(LL i = 1; i <= n - 1; i++) sum += (n - i) * q[i];
	LL cnt = n * (n + 1) / 2;
	p[1] = (cnt - sum) / n;
	se.insert(p[1]);
	for(LL i = 2; i <= n; i++){
		p[i] = p[i - 1] + q[i - 1];
		se.insert(p[i]);
	}
	for(LL i = 1; i <= n; i++) {
		if(p[i] < 1 || p[i] > n) { flag = true; break;}
	}
	if(se.size() != n) flag = true;
	if(cnt < sum || (cnt - sum) % n != 0 || flag)
		puts("-1");
	else {
		for(LL i = 1; i <= n - 1; i++) cout << p[i] << " ";
		cout << p[n] << endl;
	}
	return 0;
}
/*
a[2] - a[1] = x;
a[3] - a[2] = y;
a[4] - a[3] = z;
a[4] - a[1] = z + x + y;
a[3] - a[1] = y + x;
a[2] - a[1] = x;
a[4] + a[3] + a[2] + a[1] = 2 * y + 3 * x + z + 4 * a[1]
*/

 

你可能感兴趣的:(思维,数学,算法学习与刷题记录)