ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)

A

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <utility>

using namespace std;
typedef long long ll;
const int qq = 1e5 + 10;
int n, m;
string a, b;
string c, d;

int main(){
	cin >> a >> b;
	cout << a << " " << b << endl;
	cin >> n;
	for(int i = 0; i < n; ++i){
		cin >> c >> d;
		if(c == a){
			a = d;
			cout << a << " " << b << endl;
		}	
		else if(c == b){
			b = d;
			cout << a << " " << b << endl;
		}else if(d == a){
			a = c;
			cout << a << " " << b << endl;
		}else if(d == b){
			b = c;
			cout << a << " " << b << endl;
		}
	}
	return 0;
}

B

題意:要求一個數和它的所有質因子的顏色不一樣,  要你輸出最少使用多少顏色, 以爲每一個數使用了哪種顏色

我們知道一個數的質因子之間都是互質的, 那麼我們得知如果所有質數都爲顏色1, 那麼其他數只要爲顏色2就可以得解

注意一下只需要用一種顏色的情況

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <utility>

using namespace std;
typedef long long ll;
const int qq = 1e5 + 10;
int n, m;
int prime[30] = {2, 3, 5, 7, 11, 13, 17, 19, 21, 23, 29, 31};
int vis[qq];
bool isprime[qq];

int main(){
	memset(isprime, true, sizeof(isprime));
	memset(vis, 0, sizeof(vis));
	isprime[1] = false;
	int n;	scanf("%d", &n);
	if(n == 1){
		printf("1\n");
		printf("1\n");
		return 0;
	}
	if(n == 2){
		printf("1\n1 1\n");
		return 0;
	}
	n++;
	for(int i = 2; i <= n; ++i){
		if(isprime[i])
			for(int j = i + i; j <= n; j += i)
				isprime[j] = false;
	}
	printf("2\n");
	for(int i = 2; i <= n; ++i)
		if(isprime[i])	printf("1 ");
		else	printf("2 ");
	puts("");
	return 0;
}

C

題意:要你求有多少個區間的和爲k^n此方(n >= 0)

這裏利用了一些數的特性, 說實話我覺得真的設計的很巧妙

對於某個前綴pre[i]我們處理出所有k^n + pre[i]的結果

那麼對於前綴pre[j] 我們知道 如果pre[j] = k^n + pre[i] 及 pre[j] - pre[i] = k^n

那麼區間[i, j] 即存在解

我們只需要統計計數就好了

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <utility>

using namespace std;
typedef long long ll;
const int qq = 1e5 + 10;
ll num[qq];
ll powk[qq];
ll pre[qq];
map<ll, ll> mp;
ll n, k;
#define sf(x) scanf("%lld", &x);
#define REP(i, x, n)	for(int i = x; i < n; ++i)

int main(){
	sf(n);	sf(k);
	for(int i = 1; i <= n; ++i)
		sf(num[i]);
	powk[0] = 1;
	int cnt = 1;
	if(k == -1){
		++cnt;
		powk[1] = -1;
	}else if(k != 1){
		cnt = 1;
		ll t = 1;
		while(abs(t) < 1e15){
			powk[cnt++] = t * k;
			t = t * k;
		}
	}
	REP(i, 0, cnt)	mp[powk[i]]++;
	ll ans = 0;
	for(int i = 1; i <= n; ++i){
		pre[i] = pre[i - 1] + num[i];
		ans += mp[pre[i]];
		for(int j = 0; j < cnt; ++j)
			mp[pre[i] + powk[j]]++;
	}
	printf("%lld", ans);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值