Loading...

CSP-S炸裂记

QWQ,全挂了

\(T1\) 儒略日

刚开始看到题目长度就知道这题不友好,但还是坚持把题看完了
不就是个大模拟吗
觉得好像可以做,就没看后面的题直接开肝(
现在一想觉得我真傻

思路:

有一个天数 \(x\) ,先初始化 \(day = 1\)\(mon = 1\)\(yea = -4713\)(负数表示公元前)
先算年:

\[if(x>=cd(yea)) x-=cd(yea),yea++; (cd表示当年的天数) \]

一年的天数有许多要考虑的地方

  • 是否闰年(1852年前后)
  • 是否是1852年(10月少十天)
    然后算月:

\[if(x>=cdd(mon)) x-=cdd(mon),mon++; \]

同样注意二月是否闰年,十月是否1852年
最后算日:
直接加就行
如果是1852年的10月,如果 \(x>4\) 就多加 \(10\)
于是,这样的代码就出来了:

#include<bits/stdc++.h>
using namespace std;
inline long long read() {
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)&&c!='-') c=getchar();
	if(c=='-') f=0,c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?x:-x;
}
int d[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
inline bool run(int x) {
	int y=x;
	if(x<0) y=-y-1;
	if(x<=1582) {
		return !(y%4);
	} else {
		return ((!(y%400))||((y%100)&&(!(y%4))));
	}
}
inline void slove(long long x) {
	int yea=-4713,mon=1,day=1;
	int dy=365+run(yea);
	while(x>=dy) {
		x-=dy;yea++;
		if(yea==0) yea++;
		dy=365+run(yea)-(yea==1582?10:0);
	}
	int dm=d[mon]-((yea==1582)?((mon==10)?10:0):0)+(run(yea)?((mon==2)?1:0):0);
	while(x>=dm) {
		x-=dm;mon++;
		dm=d[mon]-((yea==1582)?((mon==10)?10:0):0)+(run(yea)?((mon==2)?1:0):0);
	}
	if(mon==10&yea==1582) {
		day+=(x>4?x+10:x);
	} else {
		day+=x;
	}
	printf("%d %d %d",day,mon,(yea<0?-yea:yea));
	if(yea<0) {
		printf(" BC");
	}
	puts("");
}
int main() {
	freopen("julian.in","r",stdin);
	freopen("julian.out","w",stdout);
	int t=read();
	while(t--) {
		long long x=read();
		slove(x);
	}
	return 0;
}

可超时只得 \(40pts\)
耗时:\(1h45min\)

\(T2\) 动物园

这一题挂得最惨 \(QWQ\)

一开始觉得这题应该比较难做,还要二进制位运算
想一想觉得是先求一共要多少种饲料,然后根据排列组合求出总方案数再减已知的动物数就行
像这样:

for(int i=1;i<=m;i++) {
      int p=read(),q=read();
      for(int j=1;j<=n;j++) {
            if((a[j]>>p)&1) {
                  cnt++;
                  v[q]=true;
                  break;
            }
           }
}
while(cnt--) {
      ans=(ans<<1)|1;
}
cout<<ans-n;

前两个样例都过了,但大样例没过
觉得正常,只要有部分分就行
可现实就是爆零了
耗时:\(30min\)

\(T3\) 函数调用

一看就知道是可以打暴力的题
先打了个暴力,然后发现不仅时间会超,空间也会爆
关于时间:
没遇到乘运算先把要乘的数累乘起来,遇到加运算时再一起乘,会快一点
然后有一些特殊条件如“函数调用关系构成一棵树”:用链式前向星来存,空间会小一点
\(Code\)

#include<bits/stdc++.h>
using namespace std;
inline int read() {
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)&&c!='-') c=getchar();
	if(c=='-') f=0,c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?x:-x;
}
const int mod=998244353;
int o[100002],b[100002],p[100002];
int a[100002],cnt;
int n,res=1;
struct function {
	int d,op,pos;
	int dy[1002];
} f[1002];
void slove(int x) {
	if(f[x].op==2) {
		res*=f[x].d;
		res%=mod;
	} else if(f[x].op==1) {
		for(int i=1;i<=n;i++) {
			a[i]*=res;
			a[i]%=mod;
		}
		a[f[x].pos]+=f[x].d;
		res=1;
	} else {
		for(int i=1;i<=f[x].d;i++) {
			slove(f[x].dy[i]);
		}
	}
}
void twenty() {
	int m=read();
	for(int i=1;i<=m;i++) {
		f[i].op=read();
		if(f[i].op==1) {
			f[i].pos=read();
			f[i].d=read();
		} else if(f[i].op==2) {
			f[i].d=read();
		} else {
			f[i].d=read();
			for(int j=1;j<=f[i].d;j++) {
				f[i].dy[j]=read();
			}
		}
	}
	res=1;
	int q=read();
	while(q--) {
		int x=read();
		slove(x);
	}
	for(int i=1;i<=n;i++) {
		printf("%d ",(a[i]*res)%mod);
	}
}
struct edge {
	int next,to;
}e[100002];
int tot,h[100002];
inline void add(int x,int y) {
	e[++tot]=(edge){h[x],y};
	h[x]=tot;
}
void dfs(int x) {
	if(o[x]!=3) {
		if(f[x].op==2) {
			res*=f[x].d;
			res%=mod;
		} else if(f[x].op==1) {
			for(int i=1;i<=n;i++) {
				a[i]*=res;
				a[i]%=mod;
			}
			a[f[x].pos]+=f[x].d;
			res=1;
		}
	} else {
		for(int i=h[x];i;i=e[i].next) {
			int y=e[i].to;
			dfs(y);
		}
	}
}
int main() {
	// freopen("call.in","r",stdin);
	// freopen("call.out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++) {
		a[i]=read();
	}
	if(n<=1000) {
		twenty();
	} else {
		int m=read();
		for(int i=1;i<=m;i++) {
			o[i]=read();
			if(o[i]==1) {
				p[i]=read(),b[i]=read();
			} else if(o[i]==2) {
				b[i]=read();
			} else {
				b[i]=read();
				for(int j=1;j<=b[i];j++) {
					add(i,read());
				}
				cnt+=b[i];
			}
		}
		int q=read();
		if(cnt==0) {
			res=1;
			while(q--) {
				int x=read();
				if(o[x]==2) {
					res*=b[x];
					res%=mod;
				} else if(o[x]==1) {
					for(int i=1;i<=n;i++) {
						a[i]*=res;
						a[i]%=mod;
					}
					a[p[x]]+=b[x];
					res=1;
				}
			}
			for(int i=1;i<=n;i++) {
				printf("%d ",(a[i]*res)%mod);
			}
		} else {
			res=1;
			while(q--) {
				int x=read();
				dfs(x);
			}
			for(int i=1;i<=n;i++) {
				printf("%d ",(a[i]*res)%mod);
			}
		}
	}
	return 0;
}

但不知为什么还是爆零了 \(TAT\)
耗时:\(1h20min\)

\(T4\)

看了题,像博弈论,又没办法打暴力。
连我自己的脑子都想不清还要电脑做?
就索性打了个 \(n=3\) 的特殊情况,20分
耗时:\(10min\)

最后各种检查花去剩下时间

没了没了 \(QWQ^n\)

posted @ 2020-11-12 00:43  CNF_Acceptance  阅读(176)  评论(0)    收藏  举报