NOIP2015 day1[tarjan][搜索][模拟][贪心]
来源:互联网 发布:深圳龙岗ug编程培训 编辑:程序博客网 时间:2024/05/21 00:49
又回到最初的起点……
而我仍是如此蒟蒻。
噗那就一步一步慢慢来吧不着急2333。
T1:模拟题,小心一个是不要枚举成1到n了,一个是写存在继续操作写习惯了,忘了打非符号。
记得昨年考的时候有个等号少写了检查了很久哈哈哈。
#include<iostream>#include<cstdio>using namespace std;int n,ans[50][50];int main(){ freopen("magic.in","r",stdin); freopen("magic.out","w",stdout); scanf("%d",&n); ans[1][(n+1)/2]=1; for(int i=2;i<=n*n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) if(ans[j][k]==i-1){ if(j==1&&k==n){ ans[j+1][k]=i; } else if(j==1){ ans[n][k+1]=i; } else if(k==n){ ans[j-1][1]=i; } else{ if(!ans[j-1][k+1])ans[j-1][k+1]=i; else ans[j+1][k]=i; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)printf("%d ",ans[i][j]); printf("\n"); } return 0;}
T2:
题意:每次从每点同时向其父节点自己已有传输信息(每点有且仅有一父节点),求多久后传到自己这里。
分析:记得当时拿的模拟分hhh.
分析一下就知道拿到自己的要在环上,所以要求最小环。
然而n三方,所以继续找没用到的特点,嗯n点n边,只要找到强连通分量就不可能一个套另一个强连通分量(不然边不够)
所以写了个诡异的dfs,思路还是tarjan.
#include<iostream>#include<cstdio>using namespace std;const int maxn=2e5+5;int mini=2e9,n,tov[maxn],dep[maxn],used[maxn];int dfs(int u,int ste){ dep[u]=ste; if(!used[tov[u]]) { if(dep[tov[u]]){ used[u]=1; return dep[u]-dep[tov[u]]+1; } int ans=dfs(tov[u],ste+1); used[u]=1; return ans; } used[u]=1; return (int)2e9;}int main(){ freopen("message.in","r",stdin); freopen("message.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&tov[i]); for(int i=1;i<=n;i++)if(!used[i]) mini=min(mini,dfs(i,1)); printf("%d",mini); return 0;}
T3:做到这里还有两个小时(一共考3h),但我,没有胆量花时间去分析,上手就暴力,最后发现好像大家分都高得吓人,这里要反思、要静下心来分析,平时考试分数不是最重要的,而且也看得出来这是简单题,划线又不按照分数划。
题意:给定一副牌,有不同的走牌方式,求怎样最快走完。
分析:(我觉得它的思路是把不能贪心的地方先枚举,剩下的贪心,不过出题人想的应该是map记忆化搜索不然不会给这么大内存。
然后就是直接分析贪心会发现不能贪心,仔细观察发现基本上问题都出现在顺子上,先把顺子给枚举了,剩下的地方就可以贪心了。
这种方法没用过,挺巧妙的。)
5min后补充:上述方法实力打脸,随机数据给了贪心太多施展自己力量的空间然后这个贪心是错的。
包括day1AK了的两位大神,跑出来的答案,都是错的。
幸好我记得去证明QAQ
下面的程序是错的QAQ
#include<iostream>#include<cstdio>#include<cstring>#define clr(x) memset(x,0,sizeof(x))using namespace std;int n,t,cur[30],num,col,mini,tot[5];int calc(){ clr(tot);int ret=0; for(int i=0;i<=14;i++)tot[cur[i]]++; while(tot[4]&&tot[2]>=2){ ret++;tot[4]--;tot[2]-=2; } while(tot[4]&&tot[1]>=2){ ret++;tot[4]--;tot[1]-=2; } while(tot[3]&&tot[2]){ ret++;tot[3]--;tot[2]--; } while(tot[3]&&tot[1]){ ret++;tot[3]--;tot[1]--; } if(cur[1]&&cur[0]&&tot[1]>=2)tot[1]--; return ret+tot[4]+tot[3]+tot[2]+tot[1];}void dfs(int ste){ if(ste>mini)return; mini=min(mini,ste+calc()); for(int i=3;i<=13;i++)if(cur[i]>=3){ cur[i]-=3;int j=i+1; for(j=i+1;j<=14;j++)if(cur[j]<3)break; else { cur[j]-=3; dfs(ste+1); } for(int k=i;k<j;k++)cur[k]+=3; } for(int i=3;i<=12;i++)if(cur[i]>=2){ cur[i]-=2;int j=i+1; for(j=i+1;j<=14;j++)if(cur[j]<2)break; else { cur[j]-=2; if(j-i>=2)dfs(ste+1); } for(int k=i;k<j;k++)cur[k]+=2; } for(int i=3;i<=10;i++)if(cur[i]){ cur[i]--;int j=i+1; for(j=i+1;j<=14;j++)if(!cur[j])break; else { cur[j]--; if(j-i>=4)dfs(ste+1); } for(int k=i;k<j;k++)cur[k]++; }}int main(){ freopen("landlords.in","r",stdin); freopen("landlords.out","w",stdout); scanf("%d %d",&t,&n); for(int i=1;i<=t;i++){ clr(cur);mini=2e9; for(int i=1;i<=n;i++){ scanf("%d %d",&num,&col); if(num>=2)cur[num]++; else if(num==1)cur[14]++; else if(col==1)cur[0]++; else cur[1]++; } dfs(0); printf("%d\n",mini); } return 0;}
我马上写个正确的,我错了QWQ
#include<iostream>#include<cstdio>#include<cstring>#define clr(x) memset(x,0,sizeof(x))using namespace std;int n,t,cur[30],num,col,mini;int calc(){ int ret=0; for(int i=0;i<=14;i++)if(cur[i])ret++; if(cur[0]&&cur[1])ret--; return ret;}void dfs(int ste){ if(ste>mini)return; mini=min(mini,ste+calc()); for(int i=3;i<=13;i++)if(cur[i]>=3){ cur[i]-=3;int j=i+1; for(j=i+1;j<=14;j++)if(cur[j]<3)break; else { cur[j]-=3; dfs(ste+1); } for(int k=i;k<j;k++)cur[k]+=3; } for(int i=3;i<=12;i++)if(cur[i]>=2){ cur[i]-=2;int j=i+1; for(j=i+1;j<=14;j++)if(cur[j]<2)break; else { cur[j]-=2; if(j-i>=2)dfs(ste+1); } for(int k=i;k<j;k++)cur[k]+=2; } for(int i=3;i<=10;i++)if(cur[i]){ cur[i]--;int j=i+1; for(j=i+1;j<=14;j++)if(!cur[j])break; else { cur[j]--; if(j-i>=4)dfs(ste+1); } for(int k=i;k<j;k++)cur[k]++; } for(int i=2;i<=14;i++)if(cur[i]>=4){ cur[i]-=4; for(int j=2;j<=14;j++)if(cur[j]>=2){ cur[j]-=2; for(int k=2;k<=14;k++)if(cur[k]>=2){ cur[k]-=2; dfs(ste+1); cur[k]+=2; } cur[j]+=2; } cur[i]+=4; } for(int i=2;i<=14;i++)if(cur[i]>=4){ cur[i]-=4; for(int j=0;j<=14;j++)if(cur[j]){ cur[j]--; for(int k=0;k<=14;k++)if(cur[k]){ cur[k]--; dfs(ste+1); cur[k]++; } cur[j]++; } cur[i]+=4; } for(int i=2;i<=14;i++)if(cur[i]>=3){ cur[i]-=3; for(int j=2;j<=14;j++)if(cur[j]>=2){ cur[j]-=2; dfs(ste+1); cur[j]+=2; } cur[i]+=3; } for(int i=2;i<=14;i++)if(cur[i]>=3){ cur[i]-=3; for(int j=0;j<=14;j++)if(cur[j]){ cur[j]--; dfs(ste+1); cur[j]++; } cur[i]+=3; }}int main(){ freopen("landlords.in","r",stdin); freopen("landlords.out","w",stdout); scanf("%d %d",&t,&n); for(int i=1;i<=t;i++){ clr(cur);mini=2e9; for(int i=1;i<=n;i++){ scanf("%d %d",&num,&col); if(num>=2)cur[num]++; else if(num==1)cur[14]++; else if(col==1)cur[0]++; else cur[1]++; } dfs(0); printf("%d\n",mini); } return 0;}
这个是对的……然后这是YJQ大神的剪枝,其实就是贪心,因为能带就带上肯定不会出问题!而且没带的也都枚举了,其实只是省去了由于排序出现的重复计算以及很多不必要的计算(比如上界的计算,就不用去跑了,直接递推);(顺序问题的精简很重要!)
CSZ做的是DP,存了四维,然后针对不同情况来计算,只需要搜顺子就可以了(因为只在顺子里数码会有影响),我觉得这个就是我上面被打脸了的那个“排除不能被贪心的因素”对应的“排除一些元素让DP好表示”;
- NOIP2015 day1[tarjan][搜索][模拟][贪心]
- Noip2015 斗地主【搜索】【贪心】
- [NOIP2015]斗地主 搜索+贪心
- NOIP2015-day1
- NOIP2015 Day1
- XJOI-NOIP2015提高组模拟题1 day1
- noip2015 day1 斗地主
- NOIP2015-Day1 详解
- NOIP2015复赛DAY1
- NOIP2015 Day1题解
- [NOIP2015]day1题解集合
- NOIP2015提高组Day1
- UOJ #151. 【NOIP2015】斗地主“加强”版【搜索+贪心
- UOJ147 [NOIP2015]斗地主 解题报告【搜索】【贪心】
- {小结}NOIP2015提高组Day1
- NOIP2015提高组Day1 Message
- [NOIP2015]Day1 T2 信息传递
- 【jzoj5086】【GDOI2017第四轮模拟day1】【数列】【搜索】
- 除法和算术右移之间的巧妙取代
- 基于字符串的Hash表效率实验分析
- JavaScript异步编程学习
- Mac apache和php
- 【Codeforces Round #200 (Div. 1)】Codeforces 343D Water Tree
- NOIP2015 day1[tarjan][搜索][模拟][贪心]
- jQuery图表(jqPlot,Highcharts)
- cmake 手册详解
- 上机1
- React.createClass( ) 和 React.Component( ) 有什么区别?
- 常用目录
- JavaScript中的arguments,callee,caller,call,appy [备忘]
- JSP中pageEncoding和charset的区别以及中文乱码解决方案
- 开年第一页