NOIP2015 Day1
来源:互联网 发布:淘宝小二几点上班 编辑:程序博客网 时间:2024/06/05 08:19
T1 神奇的幻方
喜闻乐见NOIP2017初赛阅读程序第一题
按题意模拟即可
#include<bits/stdc++.h>using namespace std;#define N 50int a[N][N];int main(){ int n,i,j; scanf("%d",&n); int x=1,y=n/2+1; a[x][y]=1; for (i=2;i<=n*n;i++){ if (x==1 && y!=n) x=n,y++; else if (x!=1 && y==n) x--,y=1; else if (x==1 && y==n) x++; else if (x!=1 && y!=n && !a[x-1][y+1]) x--,y++; else x++; a[x][y]=i; } for (i=1;i<=n;i++) for (j=1;j<=n;j++) printf("%d%c",a[i][j]," \n"[j==n]); return 0;}
T2 信息传递
显然就是在一个有向图上找一个最小的环
那么直接枚举没遍历的点BFS即可
其实正解是拓扑排序 但是按照这样子写也是对的
因为这样该找到的环依然会找到
具体例子就不举了= =
#include<bits/stdc++.h>using namespace std;#define N 200010void rd(int &x){ char c;x=0; while (c=getchar(),c<48); do x=(x<<1)+(x<<3)+(c^48); while (c=getchar(),c>=48);}struct edge{ int nxt,t;}e[N];int head[N],edge_cnt;void add_edge(int x,int y){ e[edge_cnt]=(edge){head[x],y}; head[x]=edge_cnt++;}int n,Q[N],id[N];bool mark[N];int BFS(int x){ int i,l=1,r=1,res=n; Q[1]=x; id[x]=1; while (l<=r){ int x=Q[l++]; for (i=head[x];~i;i=e[i].nxt){ int to=e[i].t; if (mark[to]) continue; if (id[to]) res=min(res,id[x]+1-id[to]); else{ id[to]=id[x]+1; Q[++r]=to; } } } for (i=1;i<=r;i++) mark[Q[i]]=1; return res;}int main(){ memset(head,-1,sizeof(head)); int i; scanf("%d",&n); for (i=1;i<=n;i++){ int x; rd(x); add_edge(i,x); } int ans=n; for (i=1;i<=n;i++) if (!mark[i]) ans=min(ans,BFS(i)); printf("%d\n",ans); return 0;}
T3 斗地主
一道很(e)好(xin)的搜索题
而且题意及其不清晰 有很多搭配规则需要选手自行领悟
主要介绍两种我自己想出来的奇怪写法
解法1
只搜索搭配的牌 把1/2/3/4张单独出的最后计算
这样可以减少很多复杂度
#include<bits/stdc++.h>using namespace std;#define N 20int n,a[N],ans;int get(){ int i; int res=0; for (i=1;i<=13;i++) if (a[i]) res++; return res+(a[14]+a[15]+1)/2;}void dfs(int t,int s,int l){ ans=min(ans,s+get());//单牌直接在这里处理 if (!t) return; int i,j,k; if (t>=8 && l<=1){ for (i=1;i<=13;i++)//四带二对 if (a[i]>=4){ a[i]-=4; for (j=1;j<=13;j++) if (i!=j && a[j]>=2){ a[j]-=2; for (k=j;k<=13;k++) if (i!=k && a[k]>=2){ a[k]-=2; dfs(t-8,s+1,1); a[k]+=2; } a[j]+=2; } a[i]+=4; } } if (t>=6 && l<=2){ for (i=1;i<=11;i++)//三顺子 if (a[i]>=3 && a[i+1]>=3){ a[i]-=3; for (j=i+1;a[j]>=3 && j<=12;j++){ a[j]-=3; dfs(t-(j-i+1)*3,s+1,2); } for (k=i;k<j;k++) a[k]+=3; } for (i=1;i<=10;i++)//双顺子 if (a[i]>=2 && a[i+1]>=2 && a[i+2]>=2){ a[i]-=2; a[i+1]-=2; for (j=i+2;a[j]>=2 && j<=12;j++){ a[j]-=2; dfs(t-(j-i+1)*2,s+1,2); } for (k=i;k<j;k++) a[k]+=2; } for (i=1;i<=13;i++)//四带二 if (a[i]>=4){ a[i]-=4; for (j=1;j<=15;j++)//可以带王 if (i!=j && a[j]){ a[j]--; for (k=j;k<=15;k++)//可以带两个相同的 if (i!=k && a[k]){ a[k]--; dfs(t-6,s+1,2); a[k]++; } a[j]++; } a[i]+=4; } } if (t>=5 && l<=3){ for (i=1;i<=8;i++)//单顺子 if (a[i] && a[i+1] && a[i+2] && a[i+3] && a[i+4]){ a[i]--; a[i+1]--; a[i+2]--; a[i+3]--; for (j=i+4;a[j] && j<=12;j++){ a[j]--; dfs(t-(j-i+1),s+1,3); } for (k=i;k<j;k++) a[k]++; } for (i=1;i<=13;i++)//三带二 if (a[i]>=3){ a[i]-=3; for (j=1;j<=13;j++) if (i!=j && a[j]>=2){ a[j]-=2; dfs(t-5,s+1,3); a[j]+=2; } a[i]+=3; } } if (t>=4 && l<=4){ for (i=1;i<=13;i++)//三带一 if (a[i]>=3){ a[i]-=3; for (j=1;j<=15;j++)//可以带王 if (i!=j && a[j]){ a[j]--; dfs(t-4,s+1,4); a[j]++; } a[i]+=3; } }}int main(){ int Case,i; scanf("%d%d",&Case,&n); while (Case--){ memset(a,0,sizeof(a)); for (i=1;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); a[x>2?x-2:(x?x+11:13+y)]++; } ans=n; dfs(n,0,1); printf("%d\n",ans); } return 0;}
解法2
搜索全部的种类
按照出的牌数从大到小搜索 防止出现重复
用A*剪枝
由于数据保证随机也可以用一个不准确的估价函数保证时间
#include<bits/stdc++.h>using namespace std;#define N 20int n,a[N],ans;void dfs(int t,int s,int l,int Las){//l用来保证出牌顺序 ans=min(ans,s+t);//单牌直接在这里处理 if (s+(int)ceil(1.0*t/max(Las,t))>=ans) return;//准确 120ms //if (s+(t+9-l-1)/(9-l)>=ans) return;//不准确 28ms if (!t) return; int i,j,k; if (t>=8 && l<=1){ for (i=1;i<=13;i++)//四带二对 if (a[i]>=4){ a[i]-=4; for (j=1;j<=13;j++) if (i!=j && a[j]>=2){ a[j]-=2; for (k=j;k<=13;k++) if (i!=k && a[k]>=2){ a[k]-=2; dfs(t-8,s+1,1,8); a[k]+=2; } a[j]+=2; } a[i]+=4; } } if (t>=6 && l<=2){ for (i=1;i<=11;i++)//三顺子 if (a[i]>=3 && a[i+1]>=3){ a[i]-=3; for (j=i+1;a[j]>=3 && j<=12;j++){ a[j]-=3; dfs(t-(j-i+1)*3,s+1,2,(j-i+1)*3); } for (k=i;k<j;k++) a[k]+=3; } for (i=1;i<=10;i++)//双顺子 if (a[i]>=2 && a[i+1]>=2 && a[i+2]>=2){ a[i]-=2; a[i+1]-=2; for (j=i+2;a[j]>=2 && j<=12;j++){ a[j]-=2; dfs(t-(j-i+1)*2,s+1,2,(j-i+1)*2); } for (k=i;k<j;k++) a[k]+=2; } for (i=1;i<=13;i++)//四带二 if (a[i]>=4){ a[i]-=4; for (j=1;j<=15;j++)//可以带王 if (i!=j && a[j]){ a[j]--; for (k=j;k<=15;k++)//可以带两个相同的 if (i!=k && a[k]){ a[k]--; dfs(t-6,s+1,2,6); a[k]++; } a[j]++; } a[i]+=4; } } if (t>=5 && l<=3){ for (i=1;i<=8;i++)//单顺子 if (a[i] && a[i+1] && a[i+2] && a[i+3] && a[i+4]){ a[i]--; a[i+1]--; a[i+2]--; a[i+3]--; for (j=i+4;a[j] && j<=12;j++){ a[j]--; dfs(t-(j-i+1),s+1,3,j-i+1); } for (k=i;k<j;k++) a[k]++; } for (i=1;i<=13;i++)//三带二 if (a[i]>=3){ a[i]-=3; for (j=1;j<=13;j++) if (i!=j && a[j]>=2){ a[j]-=2; dfs(t-5,s+1,3,5); a[j]+=2; } a[i]+=3; } } if (t>=4 && l<=4){ for (i=1;i<=13;i++)//三带一 if (a[i]>=3){ a[i]-=3; for (j=1;j<=15;j++)//可以带王 if (i!=j && a[j]){ a[j]--; dfs(t-4,s+1,4,4); a[j]++; } a[i]+=3; } for (i=1;i<=13;i++)//炸弹 if (a[i]>=4){ a[i]-=4; dfs(t-4,s+1,4,4); a[i]+=4; } } if (t>=3 && l<=5){ for (i=1;i<=13;i++)//三张牌 if (a[i]>=3){ a[i]-=3; dfs(t-3,s+1,5,3); a[i]+=3; } } if (t>=2 && l<=6){ if (a[14] && a[15]){//火箭 a[14]--; a[15]--; dfs(t-2,s+1,6,2); a[14]++; a[15]++; } for (i=1;i<=13;i++)//对子 if (a[i]>=2){ a[i]-=2; dfs(t-2,s+1,6,2); a[i]+=2; } } }int main(){ int Case,i; scanf("%d%d",&Case,&n); while (Case--){ memset(a,0,sizeof(a)); for (i=1;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); a[x>2?x-2:x?x+11:13+y]++; } ans=n; dfs(n,0,1,n); printf("%d\n",ans); } return 0;}
解法3
搜索顺子的情况 接下来用dp求出最少步数
解法4
搜索+贪心
由于这题特别奇怪 各种鬼畜的写法层出不穷 果然是NOIP 就是喜欢乱搞
这种题就是暴力踩标程 乱写能AC
Date:2017/10/26
By CalvinJin
阅读全文
0 0
- NOIP2015-day1
- NOIP2015 Day1
- noip2015 day1 斗地主
- NOIP2015-Day1 详解
- NOIP2015复赛DAY1
- NOIP2015 Day1题解
- [NOIP2015]day1题解集合
- NOIP2015提高组Day1
- {小结}NOIP2015提高组Day1
- NOIP2015提高组Day1 Message
- [NOIP2015]Day1 T2 信息传递
- NOIP2015 提高组 day1 信息传递
- noip2015 day1 t2 message 伪·题解
- NOIP2015提高组Day1斗地主
- codevs 4511 信息传递(NOIP2015 day1 T2)
- 【NOIP2015提高组Day1】信息传递
- NOIP2015 提高组 day1 信息传递
- NOIP2015 day1[tarjan][搜索][模拟][贪心]
- 微信伪造位置
- Windows Socket 异步编程(非阻塞模式) -- Select回送示例
- JVM(8)Tomcat类加载器架构
- myeclipes的各种中文乱码问题总结
- 虚拟机 Centos 设定固定IP
- NOIP2015 Day1
- banana-pi M3的linux的编译和体验
- Python爬取网页图片03
- 数据结构与算法之二分查找
- js checkbox 获取表格一行中的多个值 传递多个值
- ucUncaught TypeError: window.showModalDialog is not a function关于showModalDialog停用的问题
- Nginx,uWSGI,Django 运行环境部署
- 浅谈自定义头文件可能导致的重定义问题
- Ma下Android Studio关于gradle 下载更新的问题