2023.8.20 普及模拟2

这次又㕛叒叕垫底了。

image

哈哈哈,T1挂掉了,T3写崩了,T4暴力骗分。

T1

简化题意

判断一个 IP 地址是否合法(数据保证字符串中存在且仅存在4个被字符分开的整数),不合法时改正。

思路

简单模拟题,但我写挂了(没判断最后一位),学校数据甚至没有合法情况。

code

#include<bits/stdc++.h> using namespace std; char s[100],k[100]; int cnt;bool f; signed main(void){ freopen("ip.in","r",stdin); freopen("ip.out","w",stdout); cin>>(s+1); int n=strlen(s+1); for(int lll=0,x=0,i=1;i<=n;++i){ if(s[i]>='0'&&s[i]<='9'){ if(s[i]=='0') ++lll; x=(x<<1)+(x<<3)+(s[i]^48); } if((s[i]<'0'||s[i]>'9')||(i==n)){ if((s[i]!='.'&&i!=n)||(i==n&&s[i]<'0'||s[i]>'9')) f=1; if(x||lll){ x=min(x,255); if(x>225||lll>1) f=1; int h[5]={0},pp=0; if(!x) h[++pp]=0; while(x){ h[++pp]=x%10; x/=10; } for(int i=pp;i;--i) k[++cnt]=h[i]+'0'; x=0,lll=0; } if(k[cnt]!='.') k[++cnt]='.'; } } if(f){ puts("NO"); for(int i=1;i<=cnt-1;++i) cout<<k[i]; if(k[cnt]=='.') return 0; else cout<<k[cnt]; } else puts("YES"); return 0; }

T2

简化题面

两个序列 A,B。可以任意交换序列里的元素位置。

使排列后 i=1nai×bi 最大。

思路

考虑贪心,使序列 AB 均从小到大排序,在枚举出答案。

即如果 ai<aj,bi<bj,则一定 ai×bi+aj×bj>ai×bj+aj×bi

证明:

ai<aj,bi<bj

ajai>0,bjbi>0

(ajai)×(bjbi)>0

展开的 aj×bj+ai×biaj×biai×bj>0

移项得 ai×bi+aj×bj>ai×bj+aj×bi

证毕

code

#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10; int n,ans,a[N],b[N]; inline bool cmp(int x,int y){ return x>y; } signed main(void){ freopen("nj.in","r",stdin); freopen("nj.out","w",stdout); scanf("%lld",&n); for(int i=1;i<=n;++i){ scanf("%lld",a+i); } for(int i=1;i<=n;++i){ scanf("%lld",b+i); } sort(a+1,a+n+1); sort(b+1,b+n+1); for(int i=1;i<=n;++i){ ans+=a[i]*b[i]; } printf("%lld\n",ans); }

T3

洛谷原题P1764

思路

考场时用的是 洛谷原题P2040 的做法,只能跑过 n4 的数据。
正解是开两个数组分别去存黑色和白色的情况,在一行一行的搜索,并判断是否符合。两种情况的答案取小。

code

#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int dx[]={0,1,0,-1,0}; const int dy[]={0,0,1,0,-1}; int n,a[20][20],b[20][20]; int ans,ans1=inf,ans2=inf; int vis1[20][20],vis2[20][20]; inline bool check1(int x,int y){ if(!x||!y) return 0; int res=a[x][y]; for(int i=0;i<5;++i){ int xx=x+dx[i],yy=y+dy[i]; res+=vis1[xx][yy]; } return res&1; // return (a[x][y]+vis1[x][y]+vis1[x+1][y]+vis1[x-1][y]+vis1[x][y+1]+vis1[x][y-1])&1; } inline void dfs1(int x,int y,int tot){ if(tot>=ans1) return ; if(y==n+1) y=1,++x; if(x==n+1){ for(int i=1;i<=n;++i) if(check1(n,i)) return ; ans1=tot; return ; } vis1[x][y]=0; if(!check1(x-1,y)) dfs1(x,y+1,tot); vis1[x][y]=1; if(!check1(x-1,y)) dfs1(x,y+1,tot+1); } inline bool check2(int x,int y){ if(!x||!y) return 0; int res=b[x][y]; for(int i=0;i<5;++i){ int xx=x+dx[i],yy=y+dy[i]; res+=vis2[xx][yy]; } return res&1; // return (b[x][y]+vis2[x][y]+vis2[x+1][y]+vis2[x-1][y]+vis2[x][y+1]+vis2[x][y-1])&1; } inline void dfs2(int x,int y,int tot){ if(tot>=ans1||tot>=ans2) return ; if(y==n+1) y=1,++x; if(x==n+1){ for(int i=1;i<=n;++i) if(check2(n,i))//判断最后一行是否都翻上 return ; ans2=tot; return ; } vis2[x][y]=0;//vis:0:不翻 1:翻 //只有上一行的棋的状态为需要的状态,才会往下搜 if(!check2(x-1,y)) dfs2(x,y+1,tot); vis2[x][y]=1; if(!check2(x-1,y)) dfs2(x,y+1,tot+1); } signed main(void){ freopen("fz.in","r",stdin); freopen("fz.out","w",stdout); scanf("%d",&n); char s; for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ cin>>s; if(s=='b') a[i][j]=1; if(s=='w') b[i][j]=1; } } dfs1(1,1,0);dfs2(1,1,0); int ans=min(ans1,ans2); if(ans==0x3f3f3f3f) puts("Impossible"); else printf("%d\n",ans); return 0; }

T4

简化题面

给定 n , 使得 n=a!b! 。问有多少组 a,b 并输出每组 a,b

思路

根据定义,n 其实就是把 ab 之间的数字乘起来,乘法的增长速率是很大的,也就是说 ab 的差值不会很大,很显然不超过 20

所以可以枚举 c=ab,那么一定有 acnbc .

这样的话 ab 也是在一个很小的范围内,可以直接枚举了。

code

#include<bits/stdc++.h> #define int __int128 using namespace std; const int N=22; int T,n,x,y,k,cnt,a[N],b[N]; inline int read(){ int x=0;bool f=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=1;s=getchar();} while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+(s^48);s=getchar();} return f?-x:x; } inline void write(int x){ if(x<0) x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } signed main(void){ freopen("jc.in","r",stdin); freopen("jc.out","w",stdout); T=read(); while(T--){ n=read();cnt=0; if(!n||n==1){ puts("-1"); continue; } a[++cnt]=n;b[cnt]=n-1; for(int i=2;i<=20;++i){ //a^d<=x<=b^d x=pow(n,1.0/i);//a while(1){ y=x-i+1;k=1;//b for(int j=y;j<=x;++j) k*=j; if(k>n) break; if(k==n&&y!=1){ a[++cnt]=x; b[cnt]=y-1; } ++x; } } write(cnt);putchar('\n'); for(int i=cnt;i;--i){ write(a[i]);putchar(' '); write(b[i]);putchar('\n'); } } return 0; }

总结

这次比赛,打到 9:30 就去干别的了,主要还是进度太垮了,T1因此报废,T4也只骗了10分。

哈哈哈,T1,T3题面上分别有要输出 YesImpossible。但学校数据点竟然都没有这种情况,真是吸取总司令的经验。


__EOF__

本文作者GOD_HJ
本文链接https://www.cnblogs.com/GOD-HJ/p/17643632.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   GOD_HJ  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示