Codeforces Round 560 (Div 3)(A - F)

Codeforces Round 560 (Div. 3)

Dashboard - Codeforces Round 560 (Div. 3) - Codeforces

A. Remainder(模拟)

思路:模拟取余操作 , 只需考虑数字的后 x 位变成要变成的数字即可。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n , x , y;
int a[N] , res;

signed main(){

	cin >> n >> x >> y;
	for(int i = 1 ; i <= n ; i ++) scanf("%01d" , &a[i]);
	reverse(a + 1 , a + 1 + n);
	y += 1;
	for(int i = 1 ; i <= x ; i ++){
		if(i == y){
			if(a[i] == 0) res += 1;
		}else{
			if(a[i] == 1) res += 1;
		}
	}
	cout << res;

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

B. Polycarp Training(排序)

思路:对比赛按照从小到大排序 , 贪心的去训练。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n , a[N];

signed main(){

	cin >> n;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	sort(a + 1 , a + 1 + n);
	int now = 0;
	for(int i = 1 ; i <= n ; i ++){
		if(a[i] >= (now + 1)) now += 1;
	}
	cout << now;

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

C. Good String(模拟)

思路:手模了一下 ,没什么性质 , 直接模拟即可 , 这里我每个字符串去匹配下一个与其不同的字符串 , 加到答案中即可。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

/*
ooa
*/

int n , cnt;
string s , ans;

signed main(){

	cin >> n >> s;
	s = '~' + s;
	
	int now = 0;
	for(int i = 1 ; i <= n ; i = now + 1){
		ans += s[i];
		cnt += 1;
		bool tag = 0;
		for(int j = i + 1 ; j <= n ; j ++){
			if(s[j] != s[i]){
				tag = 1;
				now = j;
				break;
			}
		}
		if(!tag) break;
		ans += s[now];
		cnt += 1;
	}
	
	if(cnt & 1) cnt -= 1;
	cout << n - cnt << "\n";
	for(int i = 0 ; i < cnt ; i ++) cout << ans[i];
	cout << "\n"; 

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

D. Almost All Divisors(思维 + 数论)

思路:首先想到的就是分奇偶 , 奇数会比偶数多一个平方因子 , 然后把所有因子排序后 , 要判断对应位置相乘是否都相等。还有一个坑点 , 就是要求这 n 个数要是(所有因子) , 因此如果满足上面条件 , 还要额外检查因子是否全 , 因为即使因子不全也满足对应位置相乘都相等。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n , t , a[N];
map<int,int>all;
bool judge(){
	map<int,int>mp;
	if(n & 1){
		for(int i = 1 ; i <= n / 2 + 1 ; i ++){
			mp[a[i] * a[n + 1 - i]] += 1;
		}
	}else{
		for(int i = 1 ; i <= n / 2 ; i ++){
			mp[a[i] * a[n + 1 - i]] += 1;
		}
	}
	return mp.size() == 1;
}
bool judge1(int x){
	
	for(int i = 2 ; i * i <= x ; i ++){
		if(x % i == 0){
			if(!all[i]) return 0;
			if(!all[x / i]) return 0;
		}
	}
	return 1;
}

signed main(){

	IOS
	cin >> t;
	
	while(t --){
		
		cin >> n;
		all.clear();
		for(int i = 1 ; i <= n ; i ++) cin >> a[i] , all[a[i]] += 1;
		sort(a + 1 , a + 1 + n);
		
		//第一次判断
		if(!judge()){
			cout << "-1\n";
		}else{
			int now = 0;
			if(n & 1){
				now = a[(n + 1) / 2];
				now = now * now; 
			}else{
				now = a[1] * a[n];
			}
			//第二次判断
			if(judge1(now)){
				cout << now << "\n";
			}else{
				cout << "-1\n";
			}			
		}
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

E. Two Arrays and Sum of Functions(思维 + 排序)

思路:很经典的一道题 , 首先我们考虑每个位置 i 被覆盖的次数应该是 cnt[i] = i * (n + 1 - i); 就是左边可选的端点数乘右边的端点数。

这样我们可以把答案表示成下面这个形式。

a n s = ∑ 1 n c n t [ i ] ∗ a [ i ] ∗ b [ i ] ans=\sum_{1}^{n}cnt[i] *a[i]*b[i] ans=1ncnt[i]a[i]b[i]

现在 cnt[i] 与 a[i] 已知 , 要重排b数组最小化 ans ,只要贪心的让大的数去配对小的数就好了。

注意会有一些小的实现细节。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 998244353;
typedef pair<int,int>PII;

int a[N] , b[N] , n , cnt[N] , res;

signed main(){

	IOS
	cin >> n;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	for(int i = 1 ; i <= n ; i ++) cin >> b[i];
	for(int i = 1 ; i <= n ; i ++) cnt[i] = i * (n - i + 1);
	for(int i = 1 ; i <= n ; i ++) a[i] = a[i] * cnt[i];
	sort(a + 1 , a + 1 + n ,
		[&](int a , int b){
			return a > b;
		}
	);
	sort(b + 1 , b + 1 + n ,
		[&](int a , int b){
			return a < b;
		}
	);
	
	for(int i = 1 ; i <= n ; i ++){
		res = (res + a[i] % mod * b[i] % mod) % mod;
	}
	
	cout << res ;

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

F. Microtransactions(二分 + 贪心)

思路:显然时间是满足二分性的 , 考虑去二分答案 。 那么如何二分答案呢 , 我们可以观察到一个商品是可以有很多个打折时间的 , 那么我们在二分答案的时候选择哪一个打折时间去购买呢 ? 这里我们要用到贪心的思想 ,对于一个商品的多个打折时间 , 我们选择满足条件的最靠后的打折时间去购买 , 这样能最大化的利用资源。

注意细节即可。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n , m;
int cnt[N] , sum , cnt_1[N];
map<int , vector<int>>mp;//某个商品的所有打折时间
map<int , vector<int>>ed;//某个时间可以处理的商品

bool judge(int t){
	
	//处理每个商品的最晚打折时间
	ed.clear();
	for(auto [x , y] : mp){
		int res = 0;
		for(auto v : y) if(v <= t) res = max(res , v);
		ed[res].push_back(x);
	}
	
	for(int i = 1 ; i <= n ; i ++) cnt_1[i] = cnt[i]; 
	
	int need = 0;
	
	for(auto [x , y] : ed){
		int now = (x - need);//当前时刻的可用资源
		for(auto v : y){
			if(cnt_1[v] <= now){
				now -= cnt_1[v];
				need += cnt_1[v];
				cnt_1[v] = 0;
			}else{
				cnt_1[v] -= now;
				need += now;
				break;
			}
		}
	}
	//未打折使用的资源
	for(int i = 1 ; i <= n ; i ++) need += cnt_1[i] * 2;
	
	return need <= t;
}

signed main(){

	IOS
	cin >> n >> m;
	for(int i = 1 ; i <= n ; i ++) cin >> cnt[i];
	for(int i = 1 ; i <= m ; i ++){
		int x , y;
		cin >> x >> y;
		mp[y].push_back(x);
	}
	
	int l = 0 , r = 4e5;

	while(l < r){
		int mid = (l + r) >> 1;
		if(judge(mid)) r = mid;
		else l = mid + 1;
	}

	cout << l << "\n";

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

你可能感兴趣的:(算法)