集训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&∑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;
}
吃完饭回来听虎哥说我午休没睡乱动塑料袋被记违纪了。
有没有一种可能,我会成为班里第一个因为违纪被老班干的人,一种说法,不一定对(安详