2022.5.24———HZOI【高一普及组膜你赛4】爆零记
还是成绩综述
%%%冬天雨姐姐和爱摸鱼的"kkksc03"二位dalao共同AK
然后我这个傻蛋莫名其妙必然地爆了0。。。
傻蛋爆0的原因
做T1的时候瞬间打出来状压,结果搞错数据范围压错了,然后想改的时候又不会改了,时间已经过去了1h,所以直接开T2
T2一看tarjan强连通分量的板子,然鹅我把tarjan原理甚至都忘了结果随便想了想就吃了个低保过去了
到目前还剩一个多小时
T3一看题是道不难的数论,gcd和lcm,我一上来夸夸先判定了两个错误情况【这种情况下能拿20pts】,然后又判定了至少有的答案数【这种情况下能再拿10pts】,还有一种情况没有考虑到,如果考虑到能再拿10pts。然后开始想正解,我一看就觉得是枚举,然鹅我想不出来枚举的范围【正解就是确定枚举范围】,所以我就萌生了邪恶的想法:打表。。。【不要打表阿!代码长得很,爆零两行泪】
然后我测试了半天把表打了出来,就剩十分钟了,然后上交没有提示我代码太长,喜悦
然鹅比赛结束T3就CE了,然后他编译信息是这个...
。。。然后把表删了拿了30pts,然鹅还是倒第二。。
以前学的板子还得时常回顾阿!!!不能学了新的忘了旧的阿!!!
题
T1 The Prices
这m的数据显然就是状压了 没什么好说的,注意初始化就行了。。
CODE
// dfs(); // mem(f,0x3f);//第一个版本的【错误】状压 // // f[1][1] = c[1][1]+d[1]; // for(re s = 1 ; s <= S ; ++ s){ // for(re j = 1 ; j <= m ; ++ j){//该选第j个 // for(re i = 1 ; i <= n ; ++ i){ // if(i & s != 0){//之前到过这个超市 // f[s][j] = MIN(f[s][j],f[s][j-1]+c[i][j]); // } // else{//之前没到过这个超市 // f[s][j] = MIN(f[s][j],f[s][j-1]+c[i][j]+d[i]); // } // } // } // } // mem(f,0x3f);//第二个版本的【错误】状压 // f[0][0] = 0; // int res,bin; // for(re s = 1 ; s <= S ; ++ s){ // for(re i = 1 ; i <= n ; ++ i){ // for(re j = 1 ; j <= S ; ++ j){ // if(j & s == 0){ // res=0,bin=1; // for(re k = 1 ; k <= m ; ++ k){ // if(bin & j != 0){ // res += c[i][k]; // } // bin<<=1; // } // f[s|j][n] = MIN(f[s|j][n],f[s][n]+d[i]+res); // } // } // } // } // // printf("%d",f[S][m]); // printf("%d",f[S][n]); #include <iostream> #include <iomanip> #include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <ctime> #define ll long long #define mem(x,y) memset(x,y,sizeof(x)) #define re register int #define char_phi signed #define MARK printf("~~~") #define _MARK printf("###") #define LMARK printf("@@@@@@") #define SLEEP printf("💤") #define SLEEPER printf("(~﹃~)~zZ") #define STUDY printf("📕📕📕") #define ot(x) printf("%d",x) #define lot(x) printf("%lld",x) #define _ putchar(' ') #define endl putchar('\n') #define MAX(x,y) ((x > y) ? (x) : (y)) #define MIN(x,y) ((x < y) ? (x) : (y)) #define N 105 #define M 20 #define LARGE 70005 #define INF 1145141919 using namespace std; ll n,m,S,final_ans; ll d[N]; ll c[N][M],f[N][LARGE]; inline ll read(){ ll x = 0;char c; while(!isdigit(c = getchar())); do{ x = (x << 3) + (x << 1 ) + (c & 15); }while(isdigit(c = getchar())); return x; } void work(){ //这显然是个dp。。但是n,m怎么这么小,可能是状压? //对于第i个商店的第j个物品 //算了我先打深搜 //c[i][j]不会爆long long吧 //f[s][j] 表示状态为s时选j个物品的最小价钱 //这n没法状压阿,那我只能深搜了 n = read(),m = read(); S = (1 << m) - 1;//1 0 0 0 0 -> 0 1 1 1 1 for(re i = 1 ; i <= n ; ++ i){ d[i] = read(); for(re j = 1 ; j <= m ; ++ j){ c[i][j] = read(); } } //0鸣姐姐的思路跟我就是不一样,欸,我一个莎比去压超市然后忽然发现不行 //想换成压货物但是不会处理路费辽 //你看人家0鸣姐姐多牜,直接先假设都是第一次来这个超市哎哎哎 //dp这里还是玄学,不太明白,不过乱搞还有乱调整顺序总觉得能搞出来。。 for(re i = 1 ; i <= S ; ++ i){//所有的状态 f[0][i] = INF;//可是为什么从1开始才行 } for(re i = 1 ; i <= n ; ++ i){//枚举每一个超市 // SLEEP; for(re s = 0 ; s <= S ; ++ s){//0鸣姐姐的高明之处 f[i][s] = f[i-1][s] + d[i]; // ot(f[i][s]),_; } // endl; for(re s = 0 ; s <= S ; ++ s){ for(re j = 1 ; j <= m ; ++ j){ // ot(s),_,ot((1 << (j-1))),_,ot((s & (1 << (j-1)))),endl; if((s & (1 << (j-1))) == 0){//状态中没选这个货物 // lot(s),_;//你奈奈个头 位运算一定要多加括号 害我调半天 f[i][s | (1 << ( j-1))] = MIN(f[i][s | (1 << (j-1))],f[i][s] + c[i][j]); } } } endl; for(re s = 0 ; s <= S ; ++ s){//在这个超市啥都不选 f[i][s] = MIN(f[i][s],f[i-1][s]); } } // for(re i = 0 ; i <= n+1 ; ++ i){ // SLEEP; // for(re s = 0 ; s <= S ; ++ s){ // ot(f[i][s]),_; // } // endl; // } lot(f[n][S]); } char_phi main(){ freopen("prices.in","r",stdin); freopen("prices.out","w",stdout); work(); return 0; }
T2 上白泽慧音
tarjan板子。。
CODE
#include <iostream> #include <iomanip> #include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #define ll long long #define mem(x,y) memset(x,y,sizeof(x)) #define re register int #define char_phi signed #define MARK printf("~~~") #define _MARK printf("###") #define LMARK printf("@@@@@@") #define SLEEP printf("💤") #define SLEEPER printf("(~﹃~)~zZ") #define STUDY printf("📕📕📕") #define ot(x) printf("%d",x) #define lot(x) printf("%lld",x) #define _ putchar(' ') #define endl putchar('\n') #define MAX(x,y) ((x > y) ? (x) : (y)) #define MIN(x,y) ((x < y) ? (x) : (y)) #define N 10000005 #define E 1000005 using namespace std; int n,m,final_ans,star_cnt,tarjan_id,strong_num,top,toper,mxid,maxer; bool vis[N]; int head[E<<1],dfn[N],low[N],belong[N],siz[N],s[N]; struct star{ int v,nxt; }e[E<<1]; inline int read(){ int x = 0;char c; while(!isdigit(c = getchar())); do{ x = (x << 3) + (x << 1 ) + (c & 15); }while(isdigit(c = getchar())); return x; } inline void star_add(int u,int v){ e[++ star_cnt].v = v , e[star_cnt].nxt = head[u] , head[u] = star_cnt; } void tarjan(int x){ dfn[x] = low[x] = ++ tarjan_id; s[++ top] = x,vis[x] = true; for(re i = head[x] ; i ; i = e[i].nxt){ if(dfn[e[i].v] == false){//树枝边 tarjan(e[i].v); low[x] = MIN(low[x],low[e[i].v]); } else if(vis[e[i].v] == true){//返祖边 low[x] = MIN(low[x],dfn[e[i].v]); } } if(low[x] == dfn[x]){ ++ strong_num,toper = 0; do{ toper = s[top],-- top,vis[toper] = false; belong[toper] = strong_num,++ siz[strong_num]; }while(toper != x); } } void work(){ //这个题是判环!可恶额 n = read(),m = read(); for(re i = 1,a,b,t ; i <= m ; ++ i){ a = read(),b = read(),t = read(); (t == 1) ? (star_add(a,b)) : (star_add(a,b),star_add(b,a)); // if(t == 1){ // star_add(a,b); // } // else{ // star_add(a,b); // star_add(b,a); // } } for(re i = 1 ; i <= n ; ++ i) if (dfn[i] == 0) tarjan(i);//应该不是森林? // SLEEP; // for(re i = 1 ; i <= strong_num+2 ; ++ i){ // ot(siz[i]),_; // } // endl; // for(re i = 1 ; i <= n ; ++ i){ // ++ siz[belong[i]]; // } for(re i = 1 ; i <= strong_num ; ++ i){ maxer = MAX(maxer,siz[i]); } ot(maxer),endl; for(re i = 1 ; i <= strong_num ; ++ i){ if(siz[i] == maxer){ mxid = i; // break; } } for(re i = 1 ; i <= n ; ++ i){ if(belong[i] == mxid){ ot(i),_; } } } char_phi main(){ freopen("classroom.in","r",stdin); freopen("classroom.out","w",stdout); work(); return 0; }
T3 最大公约数和最小公倍数问题
这个题明确一点就行了,a*b/gcd = lcm,所以a*b = gcd*lcm,而考试的时候我还不知道...(我太逊了qAq)
CODE
#include <iostream> #include <iomanip> #include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #define ll long long #define mem(x,y) memset(x,y,sizeof(x)) #define re register int #define char_phi signed #define MARK printf("~~~") #define _MARK printf("###") #define LMARK printf("@@@@@@") #define SLEEP printf("💤") #define SLEEPER printf("(~﹃~)~zZ") #define STUDY printf("📕📕📕") #define ot(x) printf("%d",x) #define lot(x) printf("%lld",x) #define _ putchar(' ') #define endl putchar('\n') using namespace std; ll GCD,LCM,MXX,final_ans,SQ; // ll c[1005][1005]; inline ll read(){ ll x = 0;char c; while(!isdigit(c = getchar())); do{ x = (x << 3) + (x << 1 ) + (c & 15); }while(isdigit(c = getchar())); return x; } ll gcd(ll xx,ll yy){ return ((yy == 0) ? (xx) : (gcd(yy,xx%yy))); } void work(){ //😔 //怎么今天这题都觉得涉及到组合一类,组合数我倒是会,但是我不知道怎么用c++实现组合具体内容阿 //显然n不能>m,然后gcd(x,y) = n,那么n为x,y的共同因子 //x,y又是lcm(x,y)的因子,所以gcd(x,y)必定是lcm(x,y)的因子 //如果不是直接判断输出0? //说说我的暴力想法: //x,y至少有一个满足,即x=n,y=m//update:好像不对 //首先先把m一直除上n,然后把得到的数进行质因数分解 //然后就不会了 超级枚举把 //我忽然又有了邪恶的想法 我能不能打表阿 //好家伙,我发现了这万恶的题,他竟然x0,y0可以是同样的值交换过来一遍,好家伙那就得*2 //打表程序在跑了,但是打出来的表应该交不上去??(可恶额) //霍 跑的好慢 GCD = read(),LCM = read(); if(GCD == LCM){ goto CHAR_PHI; } MXX = GCD * LCM,SQ = sqrt(MXX); for(ll i = GCD ; i <= SQ ; ++ i){ if((MXX % i == 0) && gcd(MXX/i,i) == GCD) ++ final_ans; } ot((final_ans << 1)); return; CHAR_PHI:{ puts("1"); exit(0); } } char_phi main(){ freopen("gcdpro.in","r",stdin); freopen("gcdpro.out","w",stdout); work(); return 0; }
唉,这三道题都很水,然而我在这里爆0了,不过也指出了我的弱点
复习阿!之前学过的知识!巩固!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现