Codeforces Round #552 (Div. 3)

Codeforces Round #552 (Div. 3)

休闲VP发现打的真的太休闲了,完全没有比赛的氛围

A,B

不管

C

暴力跑第一轮和最后一轮

中间的轮数直接做除法

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
inline int read(){
	int v = 0,c = 1;char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') c = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		v = v * 10 + ch - 48;
		ch = getchar();
	}
	return v * c;
}
LL aaa,bbb,ccc;
LL ans;
int aa[5],bb[5],cc[5];
inline LL work(LL x,LL a,LL b,LL c){
	for(int j = x;j <= 7;++j){
		if(j == 1 || j == 4 || j == 7) a--;
		if(j == 2 || j == 6) b--;
		if(j == 3 || j == 5) c--;
		if(a < 0 || b < 0 || c < 0) return j - x;	
	}
	LL week,day;
	LL resta = a / 3;
	LL restb = b / 2;
	LL restc = c / 2;
	week = min(resta,min(restb,restc));
	LL ans = week * 7 + 7 - x + 1;
	a = a - week * 3,b -= week * 2,c -= week * 2;
	for(int j = 1;j <= 7;++j){
		if(j == 1 || j == 4 || j == 7) a--;
		if(j == 2 || j == 6) b--;
		if(j == 3 || j == 5) c--;
		ans++;
		if(a < 0 || b < 0 || c < 0) return ans - 1;
	}
	for(int j = 1;j <= 7;++j){
		if(j == 1 || j == 4 || j == 7) a--;
		if(j == 2 || j == 6) b--;
		if(j == 3 || j == 5) c--;
		ans++;
		if(a < 0 || b < 0 || c < 0) return ans - 1;
	}
}
int main(){
	cin >> aaa >> bbb >> ccc;
	aa[1] = 4,aa[2] = 7,aa[3] = 8; 
	bb[1] = 6,bb[2] = 9;
	cc[1] = 5,cc[2] = 10;
	for(int i = 1;i <= 7;++i){
		ans = max(ans,work(i,aaa,bbb,ccc));
	//	printf("%d %d\n",i,ans);
	}
	cout << ans;
	return 0;
}

D

之前贪心发现贪错了

发现操作分位3种

\(x-1\),\(y - 1\),\(x-1,y+1\)

可以证明当\(s[i] = 1\)时,使用\(x - 1,y+1\)一定不会更劣

所以就尽可能的在\(s[i] = 1\)时使用\(x\)就好了

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 2e5 + 3;
int s[N];
int n,a,b,num;//b:太阳能 
inline int read(){
	int v = 0,c = 1;char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') c = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		v = v * 10 + ch - 48;
		ch = getchar();
	}
	return v * c;
}
int main(){
	n = read(),a = read(),b = read(),num = 0;
	int rest = b;
	for(int i = 1;i <= n;++i) s[i] = read();
	for(int i = 1;i <= n;++i){
		if(a == 0 && rest == 0) {printf("%d\n",i - 1);return 0;}
		if(s[i] == 0 && rest != 0) rest--;
		else if(s[i] == 0 && rest == 0) a--;
		else if(s[i] == 1 && rest != b){
			if(a == 0) rest--;
			else {
				a--;
				if(rest != 0) num++;
				rest++; 
			}	
		}
		else if(s[i] == 1 && rest == b){
			rest--;
		}
//		printf("%d %d\n",a,rest);
	}
	printf("%d\n",n);
	return 0;
}
/*
19 7 4
0 0 1 1 0 1 0 0 1 0 1 1 1 1 1 1 0 0 1
*/ 

E

直接用双向链表模拟就好了

时间复杂度可以证明

暴力删除

懒得写链表,就用set维护

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<set>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 2e5 + 3;
int a[N];
int L[N];
int R[N];
bool book[N];
int n,k;
int ans[N];
set<pii> s;
set<int> ss; 
int sta[N];
int tot;
set<pii>::iterator it;
set<int>::iterator iit;
inline int read(){
	int v = 0,c = 1;char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') c = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		v = v * 10 + ch - 48;
		ch = getchar();
	}
	return v * c;
}
int main(){
	int now = 1;
	n = read(),k = read();
	for(int i = 1;i <= n;++i) a[i] = read(),s.insert(mk(a[i],i)),ss.insert(i);
	while(!s.empty()){
		it = s.end();it--;
		pii x = *it;
		tot = 0;
		iit = ss.lower_bound(x.se);
		for(int num = 0;num <= k;--iit,++num){
		//	printf("%d ",*iit);
			ans[*iit] = now;
			s.erase(mk(a[*iit],*iit));
			sta[++tot] = *iit;
			if(iit == ss.begin()) break;
		}
		iit = ss.lower_bound(x.se);
		for(int num = 0;num <= k && iit != ss.end();++iit,++num){
		//	printf("%d ",*iit);
			ans[*iit] = now;
			s.erase(mk(a[*iit],*iit));
			sta[++tot] = *iit;	
		}
	//	puts("");
		for(int i = 1;i <= tot;++i) ss.erase(sta[i]);
		if(now == 1) now = 2;
		else now = 1;
	}
	for(int i = 1;i <= n;++i) printf("%d",ans[i]);
	return 0;
}

F

发现\(k\)这么小,肯定有东西

发现购买的物品一定是前\(k\)

\(k\)小一定是从大往小买

直接排序

所以我们设\(f_i\)表示前\(i\)个物品的最小花费

每次枚举用了哪一个优惠

或者不用优惠就好了

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 2e5 + 3;
inline int read(){
	int v = 0,c = 1;char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') c = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		v = v * 10 + ch - 48;
		ch = getchar();
	}
	return v * c;
}
int n,k,m;
int bar[N];
int f[N];
int a[N];
int sum[N];
int main(){
	n = read(),m = read(),k = read();
	for(int i = 1;i <= n;++i) a[i] = read();
	for(int i = 1;i <= m;++i){
		int x = read(),y = read();
		bar[x] = max(bar[x],y);	
	}
	sort(a + 1,a + n + 1);
	reverse(a + 1,a + k + 1);
	for(int i = 1;i <= k;++i) sum[i] = sum[i - 1] + a[i];
	memset(f,0x3f,sizeof(f));
	f[0] = 0;
//	for(int i = 1;i <= k;++i) printf("%d\n",a[i]);
	for(int i = 1;i <= k;++i){
		for(int j = 1;j <= i;++j)
			f[i] = min(f[i],f[i - j] + sum[i] - sum[i - j] - (sum[i] - sum[i - bar[j]]));		
		f[i] = min(f[i],f[i - 1] + a[i]);
	}
	cout << f[k] << endl;
	return 0;
}

G

\[lcm(i,j) = \frac{i\times j}{gcd(i,j)} \]

我们就枚举\(gcd(i,j)\)

显然\(i,j\)都要是他的倍数

在枚举的时候顺带更新答案就好了

CF上开\(4\)s,\(10^7\)一个\(log\)还是可以过得

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 1e7 + 3;
const int M = 1e7;
int n;
int a[N];
LL ans = 9999999999999999;
pii id;
int vis[N];
inline int read(){
	int v = 0,c = 1;char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') c = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		v = v * 10 + ch - 48;
		ch = getchar();
	}
	return v * c;
}
int main(){
	n = read();
	for(int i = 1;i <= n;++i){
		a[i] = read();
		if(vis[a[i]]){
			if(a[i] < ans) ans = a[i],id = mk(vis[a[i]],i);	
		}
		vis[a[i]] = i;
	}
	for(int d = 1;d <= M;++d){
		int maxx1 = 0,maxx2 = 0;
		for(int x = d;x <= M;x += d){
			if(vis[x]){
				if(!maxx1) maxx1 = vis[x];
				else if(!maxx2) maxx2 = vis[x];
				else maxx2 = maxx1,maxx1 = vis[x];
				if(maxx1 != 0 && maxx2 != 0)
				if(1ll * a[maxx1] * a[maxx2] / d < ans) ans = 1ll * a[maxx1] * a[maxx2] / d,id = mk(maxx1,maxx2);
			//	printf("%d %d %d %lld\n",d,maxx1,maxx2,ans);
			}
		}
	}
	if(id.fi > id.se) swap(id.fi,id.se);
	printf("%d %d\n",id.fi,id.se);
	return 0;
}

posted @ 2019-08-26 15:48  wyxdrqcccc  阅读(181)  评论(0编辑  收藏  举报