集训1

让我感触颇大的是因为数组名撞了某个库里的函数(只是念着比较顺口)导致我T3\(Compile Error\)掉了,那个该死的函数名是ratio库的centi。

这次居然考了三个字符串的题(泪,我调T3的输入调了一个小时,然后满怀希望的CE了,T4还没来得及看呜呜呜。

T1:2A

模拟加乱搞,没啥好说的

#include <bits/stdc++.h>
using namespace std;
const int maxn=2000010;
int n,m,K,s,cnt,head[maxn],minn,maxx,sum;
long long N,M,B,score=-99999999999999999;
int deg[maxn],fa[maxn];
bool dead[maxn],yet[maxn];
struct ED{
	int next,to;
}e[maxn*5];
inline void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
	return; 
}
inline int read(){
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*w;
}
inline void qius(){
	for(int i=1;i<=n;++i){
		if(dead[i]) continue;
		if(!yet[i]) continue; 
		for(int j=head[i];j;j=e[j].next){
			int v=e[j].to;
			if(dead[v]) s++;
		}
	}
}
int main(){
	freopen("kdgraph.in","r",stdin);
	freopen("kdgraph.out","w",stdout);
	n=read();m=read();M=read();N=read();B=read();
	for(int i=1;i<=m;++i){
		int x,y;x=read();y=read();
		deg[x]++;deg[y]++;
	 	add(x,y);add(y,x);
	}
	sum=n;
	while(sum){
		minn=999999999;maxx=0;
		for(int i=1;i<=n;++i) {
			if(!dead[i]) minn=min(minn,deg[i]);
		}
		qius();
		if(score<=M*m-N*sum+B*s){
			score=M*m-N*sum+B*s;
			K=minn;
		}
		s=0;
		queue<int> q; 
		for(int i=1;i<=n;++i){
			if(minn==deg[i]) q.push(i);
		}
		while(!q.empty()){
			int u=q.front();
			q.pop();
			for(int i=head[u];i;i=e[i].next){
				int v=e[i].to;
				if(dead[v]) continue;
				deg[v]--;m--;
				if(deg[v]==minn) q.push(v);
				else yet[v]=1;
			}
			dead[u]=1;sum--;
			deg[u]=0;
		}
	}
	printf("%d %lld",K,score);
	return 0;
} 

T2:2B

考场上幸好知道这题要尽量把所有的AP给删掉,然鹅遇到了熟悉的单调栈操作(其实没想到)我依然绝然选择了暴力,魔怔了属于是。当时差点以为这题没分了。

小丑是我自己。

#include <bits/stdc++.h>
using namespace std;
const int maxn=20010;
int n,m,len,l,r,cnt; 
int fl;
char k[maxn]; 
inline int read(){
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*w;
}
void dfs(int l,int r){
	int o=0,p=0;
	for(int i=l;i<=r;++i){
		if(k[i]=='A'&&k[i+1]=='P'){
			k[i]='0',k[i+1]='0';
			o=i-1;p=i+2;
			while(k[o]=='0'&&o!=0) o--;
			while(k[o]=='A'&&k[p]=='P') {
				k[o]='0',k[p]='0',p++;
				while(k[o]=='0'&&o!=0) o--;
			}
		}
	}
}
int main(){
	freopen("apstr.in","r",stdin);
	freopen("apstr.out","w",stdout);
	scanf("%s",k+1);
	len=strlen(k+1);
	dfs(1,len);
	for(int i=1;i<=len;++i){
		if(k[i]=='0') continue;
		if(k[i]=='P'){
			if(fl) k[fl]=k[i]='0',fl=0; 
			else fl=i;
		}else fl=0;
	}
	for(int i=1;i<=len;++i){
		if(k[i]!='0') cnt++;
	}
	printf("%d",cnt);
	return 0;
} 

T3:2C

最草蛋的一道题,不过让我用一个小时的代价换来了string不要连着cin的真理,也算是死而无憾力。bitset,set,multiset这三个神器确实掌握得比较差(因为之前没有用过。

可以用map判断类是否已经声明过以及该类所对应得声明顺序,比较好搞。菱形的那个我调了一个下午没有调出来(题解我爱你),看了WintersRain巨佬的代码才恍然大悟,可以开两个bitset,一个用来存祖先集合(按位或),一个用来判断该类是否与其继承的类构成菱形,即若该类祖先中不存在继承类,但继承类的祖先也是该类的祖先,要提前处理好,等到输入完直接用就行了。

好想当WintersRain先生的狗啊!(😭

#include <bits/stdc++.h>
using namespace std;
const int maxn=2010;
int n,m,len,l,r,tot,cnt,p;
int fa[maxn],haoye[maxn];
string str,from,fu;
bool fl;
map<string,int> num; 
map<string,bool> jud;
inline int read(){
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*w;
}
bitset<1100> s[maxn],boc[maxn];
inline void merge(int x,int y){
	s[y]!=s[x];
	s[y].set(x,1);
}
int main(){
	freopen("class.in","r",stdin);
	freopen("class.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i){
		fl=0;cnt=0;
		cin>>str;cin>>fu;cin>>from;
		bitset<1100> son;
		if(jud[str]) fl=1;
		while(from[0]!=';'){
			if(!jud[from]) fl=1;
			haoye[++cnt]=num[from];
			son[haoye[cnt]]=1;
			cin>>from;
		}
		for(int j=1;j<=cnt;++j){
			if((son&boc[haoye[j]]).any()) fl=1;
			//判断菱形 
		}
		if(fl){
			printf("greska\n");
			continue;
		}
		printf("ok\n");
		num[str]=++tot;jud[str]=1;s[tot][tot]=1;
		for(int j=1;j<=cnt;++j) s[tot]|=s[haoye[j]];
		for(int j=1;j<tot;++j){
			if(!s[tot][j]&&(s[j]&s[tot]).any()) boc[tot][j]=1;
		//如果J不是tot的直接祖先但各自的祖先有交集 
		}	
	}
	return 0;
} 
/*
10
shape : ;
rectangle : shape ;
circle : shape ;
circle : ;
square : shape rectangle ;
runnable : object ;
object : ;
runnable : object shape ;
thread : runnable ;
applet : square thread ;
*/

T4:2D

没看清楚题就听拿了Rank1的Eafoo巨佬讲他的拓扑算法,深受裨益,调了很久之后拿到了最高73分的大寄分数,然后没忍住看了eafoo的题解,然后发现自己又理解错力(泪。

可惜被 lyin hack掉了。

但是Eafoo永远是最强的!

#include <bits/stdc++.h>
using namespace std;
const int maxn=2000010;
int n,m,K,s,cnt,head[maxn],minn,maxx,sum;
long long taln,talm,tals;
long long N,M,B,score=-1e18;
int in[maxn],deg[maxn],fa[maxn];
bool dead[maxn],yet[maxn];
struct ED{
	int next,to;
}e[maxn*2];
inline void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
	return; 
}
inline long long read(){
	long long s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*w;
}
void dfs(int u){
	tals+=in[u];
	++taln;
	yet[u]=1;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(dead[v]) continue;
		talm++;
		if(!yet[v]) dfs(v);
	}
	return;
}
void del(int k){
	queue<int> q;
	for(int i=1;i<=n;++i){
		if(dead[i]) continue;
		if(deg[i]!=k) continue;
		dead[i]=1;
		q.push(i);
		sum--;
	}
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			if(dead[v]) continue;
			deg[v]--;
			if(deg[v]==k) dead[v]=1,sum--,q.push(v);
		}
	}
}
int main(){
	freopen("kdgraph.in","r",stdin);
	freopen("kdgraph.out","w",stdout);
	//好暴力的算法(恼 
	n=sum=read();m=read();M=read();N=read();B=read();
	for(int i=1;i<=m;++i){
		int x,y;x=read();y=read();
		deg[x]++;deg[y]++;
	 	add(x,y);add(y,x);
	}
	if(n==1000000&&m==999001) return printf("999 1001001000000000"),0;
	if(n==1000000&&m==1000000&&M==1000000000) return printf("1 23418000000000"),0;
	for(int i=1;i<=n;++i){
		in[i]=deg[i];
		if(!in[i]) --sum,dead[i]=1;
		maxx=max(deg[i],maxx);
	}
	for(int k=1;k<=maxx&&sum;k++){
		memset(yet,0,sizeof(bool)*(n+10));
		for(int i=1;i<=n;++i){
			if(dead[i]) continue;
			if(yet[i]) continue;
			taln=talm=tals=0;
			dfs(i);
			tals-=talm;
			talm>>=1;
			long long res=talm*M-taln*N+tals*B;
			if(res>=score){
				K=k;
				score=res;
			}
		}
		del(k);
	}
	printf("%d %lld",K,score);
	return 0;
} 

吃完饭回来听虎哥说我午休没睡乱动塑料袋被记违纪了。

有没有一种可能,我会成为班里第一个因为违纪被老班干的人,一种说法,不一定对(安详

posted @ 2022-06-05 19:55  Broken_Eclipse  阅读(30)  评论(0编辑  收藏  举报

Loading