首页 > 代码库 > SDUT ACM月赛(被各种取值范围坑的无力吐槽)
SDUT ACM月赛(被各种取值范围坑的无力吐槽)
神奇的树
题目链接->>>>>>>>猛戳这
看到10^5次方当时就吓哭了,起初想到是不是x,m的奇偶数的关系,好吧我承认我想多了,wa。后来直接一咬牙暴力,水过~
#include<stdio.h> #include<string.h> #include<stdlib.h> int main() { int x,m; int flag; int cnt; while(~scanf("%d %d",&x,&m)) { flag=0; cnt=0; x=2*x; while(x) { x=x%m; x=2*x; if(!x) { flag=1; printf("Yes\n"); break; } if(cnt>=1000) break; cnt++; } //printf("%d\n",cnt); if(!flag) printf("No\n"); } return 0; }
这题实在不知道起啥名好了(两种方法)
题目链接->>>>>>>>>点我点我啊
类似划分区间的做法。一开始先把最大值最小值初始化a[0],然后往后找,要是碰到的数比当前最大数大,最大值和最小值同时指向比当前最大值大的这个数,相当于从前一个区间蹦到了后一个区间。否则的话就一直找最小值。飞哥还给了一种做法看完之后五体投地,惊为天人,其实思路差不多,只不过他是一直维护最大值而已
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; long long a[100000010]; int main() { int n,i; long long max,min; long long c; long long cnt; while(~scanf("%d",&n)) { for(i=0;i<n;i++) scanf("%lld",&a[i]); min=max=a[0]; cnt=a[0]-a[1]; for(i=1;i<n;i++) { if(max<a[i]) { max=a[i]; min=a[i]; if(i!=n-1) { c=a[i]-a[i+1]; if(cnt<c) cnt=c; } } else if(min>a[i]) { min=a[i]; c=max-min; if(cnt<c) cnt=c; } //printf("%lld %lld<<<<<",max,min); } printf("%d\n",cnt); } return 0; }
orz飞神
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> using namespace std; #define inf 999999999 int a[1100000]; int main() { int n, i, j, max1, maxv; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) { scanf("%d",&a[i]); } maxv=-inf; max1=a[0]; for(i=1;i<n;i++) { maxv=max(maxv,max1-a[i]); max1=max(max1,a[i]); } printf("%d\n",maxv); } return 0; }
炸学校(spfa+前向星)
题目链接->>>>>>>>>>点我啊点我啊
这道题其实就是一道最短路的问题,但是裸地最短路有点区别,这个是找起点到终点的最短路但是前提是每个点都得遍历到。其实就是找起点到所有点的最短,终点到所有点的最短,然后找两个和的最大值。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> #include <iostream> #include <queue> #include <string> using namespace std; #define inf 99999999999 struct node { int v,w; int next; }edge[2000010]; int dis[1010]; int vis[1010]; int head[1010]; int pp[1010]; int p[1010]; int cnt; int n; void add(int u,int v,int w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void SPFA(int s) { int i; queue<int>q; memset(vis,0,sizeof(vis)); for(i=0; i<=n; i++) { dis[i]=inf; } dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dis[v]>dis[u]+edge[i].w) { dis[v]=dis[u]+edge[i].w; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } int main() { int T,m,i,j,k; int u,v,w; int s,e; int max1; scanf("%d",&T); for(k=1;k<=T;k++) { max1=-inf; scanf("%d %d",&n,&m); memset(head,-1,sizeof(head)); memset(pp,0,sizeof(pp)); memset(p,0,sizeof(p)); cnt=0; while(m--) { scanf("%d %d %d",&u,&v,&w); add(u,v,w); add(v,u,w); } scanf("%d %d",&s,&e); SPFA(s); for(i=0;i<n;i++) { pp[i]=dis[i]; } SPFA(e); for(j=0;j<n;j++) { p[j]=dis[j]; } for(i=0;i<n;i++) { max1=max(max1,pp[i]+p[i]); } printf("Case #%d: %d\n",k,max1); } return 0; }
你猜我猜不猜你猜不猜
题目链接->>>>>>>>点击打开链接
这个题没啥好说的 找到子串就行。别忘记=1的时候的情况
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <string> #include <cmath> #include <algorithm> #include <iostream> using namespace std; int main() { char str; int x; int cnt,i; while(cin>>str>>x) { cnt=0; if(str=='A') { if(x==1) cout<<"Waysd"; else if(x==2) cout<<"Ncwcbc"; else if(x>2) { cout<<"Ncwcbc"; cnt=x-2; for(i=1;i<=cnt;i++) cout<<"ncbcwcbc"; } cout<<endl; } else if(str=='B') { if(x==1) cout<<"Nc"; else if(x==2) cout<<"Ncwcbcncbc"; else if(x>2) { cout<<"Ncwcbcncbc"; cnt=x-2; for(i=1;i<=cnt;i++) cout<<"wcbcncbc"; } cout<<endl; } } return 0; }
你打我啊(简单数字逻辑)
题目链接->>>>>>>>猛戳我
看看汉语就好了,要不然你真会打死他的。这是一道简单的数字逻辑题,也就是有名的毒酒问题。
1000桶酒编号1-1000的二进制表示法所需要的最大位数为10. (2的10次方为1024)
桶1-1000的二进制表示为:
1 00 0000 0001
2 00 0000 0010
3 00 0000 0011
... ...
100 11 1110 1000
老鼠编号1-10可理解为二进制表示中位的概念。如鼠1表示第一位为1,鼠10表示第10位为1.(从右至左)
鼠1-10的二进制表示为:
1 00 0000 0001
2 00 0000 0010
3 00 0000 0100
... ...
10 10 0000 0000
鼠1-10分别喝桶1-1000中与鼠编号相同位为1的酒。 如鼠1喝所有奇数桶,因为奇数桶的第一位都为1。
最后统计死鼠的编号。 如鼠3,鼠4,鼠5 死亡,表明桶56(00 0001 1100)有毒。
桶1-1000的二进制表示为:
1 00 0000 0001
2 00 0000 0010
3 00 0000 0011
... ...
100 11 1110 1000
老鼠编号1-10可理解为二进制表示中位的概念。如鼠1表示第一位为1,鼠10表示第10位为1.(从右至左)
鼠1-10的二进制表示为:
1 00 0000 0001
2 00 0000 0010
3 00 0000 0100
... ...
10 10 0000 0000
鼠1-10分别喝桶1-1000中与鼠编号相同位为1的酒。 如鼠1喝所有奇数桶,因为奇数桶的第一位都为1。
最后统计死鼠的编号。 如鼠3,鼠4,鼠5 死亡,表明桶56(00 0001 1100)有毒。
然后上代码
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> int a[50]; int main() { int n,i; memset(a,0,sizeof(a)); for(i=1;i<=32;i++) { a[i]=pow(2,i); } while(~scanf("%d",&n)) { for(i=1;i<=32;i++) { if(n==a[i]) printf("%d\n",i); else if(n>a[i]&&n<a[i+1]) printf("%d\n",i+1); } } return 0; }
让领导先走(拓扑排序)
没啥好说的,裸地拓扑排序,记得不要被数据吓到,坑人的
#include <stdio.h> #include <string.h> #include <stdlib.h> int map[2001][2001]; int in[2001]; int ans[2001]; int n,m,i,j,k,u,v; int topo() { for(i=1; i<=n; i++) for(j=1; j<=n; j++) if(map[i][j]) in[j]++; for(i=1; i<=n; i++) { k=1; while (in[k]) k++; ans[i]=k; in[k]=-1; for(j=1; j<=n; j++) if(map[k][j]) in[j]--; } } int main() { while(~scanf("%d %d",&n,&m)) { memset (map,0,sizeof(map)); memset (in,0,sizeof(in)); memset (ans,0,sizeof(ans)); for(i=1; i<=m; i++) { scanf("%d %d",&u,&v); map[u][v]=1; } topo(); for(i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }
SDUT ACM月赛(被各种取值范围坑的无力吐槽)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。