18.4.20 noip2015 总结+题解

今天考了noip2015年的题

个人认为比11年的简单多了...!

班上的小伙伴好多都是200+的 我刚刚210

比上次有进步 可能是昨天看了tarjan的原因吧...

考试的时候顺便想改一下自己代码的风格(不我真的不是后摇怪

好总结下这次的考试

第一题

题目大意:

给定一个正整数N  1≤N≤39 且 N 为奇数

按照以下方式构造一个矩形并输出


很简单呀 就按着他给你的这个顺序去模拟就好了

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>

using namespace std;

const int N=100;

int k,ch[100][100],step,tot;

int main(){
	freopen("magic.in","r",stdin);
	freopen("magic.out","w",stdout);
	
	scanf("%d",&k);
	tot=k*k;
	int x,y;
	x=1;
	y=k/2+1;
	step=1;
	ch[x][y]=step;
	
	while(step<tot){
		step++;
		if(x==1&&y!=k){
			x=k;
			y=y+1;
		}
		else if(y==k&&x!=1){
			x=x-1;
			y=1;
		}
		else if(x==1&&y==k)  x++;
		else{
			if(!ch[x-1][y+1]){
				x=x-1;
				y=y+1;
			}
			else  x++;
		}
		ch[x][y]=step;
	}
	
	for(int i=1;i<=k;i++){
		for(int j=1;j<=k;j++)
	    printf("%d ",ch[i][j]);
	    printf("\n");
	}
	return 0;
}

第二题

题目大意:

给你一个有向图,求其中的最小环。

数据保证每个点只有一个出度 也就是说用tarjan求最小的强连通分量也是ojbk

曾同学甚至用了并查集 高级

而我 蒟蒻本人只会 暴力迪法师(dfs)+打标记

其实复杂度和tarjan是一样的 都是O(n) 甚至还比较短小(bushi

代码(注释掉的可以不用管 是我开始写tarjan的时候搞的 还有迪法师的father也可以不要 因为这是一个有向图

//find min 环 
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;

const int N=200000+10;
const int oo=1e9;

int n,head[N],tov[N],nex[N],root,rd[N];
//int low[N],stk[N],cnt,color[N];
int dfn[N],idc,vis[N],tot,map[N],ans,k,dis[N];
bool vis1[N];

int read(){
	int t=1,ans=0;
	char x;
	x=getchar();
	while(x<'0'||x>'9'){
		if(x=='-') t=-1;
		x=getchar();
	}
	while(x>='0'&&x<='9'){
		ans=ans*10+x-'0';
		x=getchar();
	}
	return ans*t;
}

void add(int u,int v){
	tot++;
	tov[tot]=v;
	nex[tot]=head[u];
	head[u]=tot;
}

int max(int a,int b){
	return a>b?a:b;
}

/*void dfs1(int u,int fa){
	vis1[u]=true;
	for(int i=head[u];i;i=nex[i]){
		int v=tov[i];
		if(v==fa) continue;
		rd[v]++;
		if(!vis1[v]){
			dis[v]=dis[u]+1;
			dfs1(v,u);
		} 
	}
}*/

void dfs(int u,int fa,int num){
	vis[u]=num;
	dfn[u]=++idc;
	for(int i=head[u];i;i=nex[i]){
		int v=tov[i];
		if(v==fa) continue;
		if(vis[v]&&vis[v]==num) ans=min(ans,dfn[u]-dfn[v]+1);
		if(!vis[v]) dfs(v,u,num);
	}
}

int main(){
	freopen("message.in","r",stdin);
	freopen("message.out","w",stdout);
	
	scanf("%d",&k);
	for(int i=1;i<=k;i++){
		int v;a
		v=read();
		add(i,v);
	}
	
	ans=oo;
	int tim=0;
//	for(int i=1;i<=k;i++)
//	  if(!vis1[i]) dfs1(i,1,i);
	for(int i=1;i<=k;i++)
	  if(!vis[i]){
	  	tim++;
		dfs(i,i,tim);
	  }
	
	/*for(int i=1;i<=k;i++)
	  map[color[i]]++;
	
	for(int i=1;i<=cnt;i++)
	  ans=max(ans,map[i]);*/
	
	printf("%d",ans);
    return 0;
}

第三题

斗-----地-----主----!!!!

我现在满脑子斗地主bgm..

就是出牌的方式变了一点:


给定数据组数t和牌数n 问最少走多少次可以把这副牌走完

寒假集训的时候 有学长给我们说他们那一届noipAK的林荫大佬这道题是他平常怎么打斗地主 就怎么写的

然后就过了...

这道题就是暴力搜索所有情况+剪枝 还有在计算剩余步数时用了贪心: 先走四带几再走三带几

 还有走四带两张单牌比带一对更优

举个例子 比如现在牌还有 4 4 4 4 5 5 6 7 

先走四带单要两步 1. 4 4 4 4 6 7      2. 5 5 

而四带双要三次    1.. 4 4 4 4 5 5     2. 7 3. 6

剩下就是不能四带双王 所以在find最后特判了一下

其实代码还有一点漏洞就是 3 3 3 3 4 4 4 4 可以被当做一个四带两对走

但是 数据太水了 改起来太麻烦了 我竟然改过了 就没有这种情况的特判了

洛谷 斗地主加强版 题解里面有完美无缺的代码

我就把我的垃圾代码粘上来(就是写这道题的时候想换一下代码风格所以看起来可能有点丑 凑合了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define f(a,b,c) for(int a=(b);a<=(c);a++)
#define oo 10000000

using namespace std;

int t,n,a[20],c[5],ans;

int find_remain(){
	int tot = 0;
	memset(c,0,sizeof(c));
	f(i ,0 ,13)  c[a[i]]++;
	while(c[4] && c[2]>1){
		c[4]--;
		c[2]-=2;
		tot++;
	}
	while(c[4] && c[1]>1){
		c[4]--;
		c[1]-=2;
		tot++;
	}
	while(c[4] && c[2]){
		c[4]--;
		c[2]--;
		tot++;
	}
	while(c[3] && c[2]){
		c[3]--;
		c[2]--;
		tot++;
	}
	while(c[3] && c[1]){
		c[3]--;
		c[1]--;
		tot++;
	}
	return tot+c[1]+c[2]+c[3]+c[4];
}

void dfs(int now){
	if(now >= ans) return ;
	int tmp=find_remain();
	ans=min(now+tmp ,ans);
	f(i ,2 ,13)
	  if(a[i]){
			int j = i+1;
			while(a[j]) j++;
			if(j-i >= 5)
			   f(j1 ,i+4 ,j-1){
					f(k ,i ,j1) a[k]--;
			        dfs(now+1);
			        f(k ,i ,j1) a[k]++;
			   }			
	  }
	f(i ,2 ,13)
	  if(a[i] >= 2){
			int j = i+1;
			while(a[j] >= 2) j++;
			if(j-i >= 3)
			  f(j1 ,i+2 ,j-1){
			  	f(k ,i ,j1) a[k]-=2;
				dfs(now+1);
				f(k ,i ,j1) a[k]+=2;
			  }		
	  }
	f(i ,2 ,13)
	  if(a[i] >= 3){
	  	    int j = i+1;
	  	    while(a[j]>=3) j++;
	  	    if(j-i >= 2)
	  	       f(j1 ,i+1 ,j-1){
	  	       	  f(k ,i ,j1) a[k]-=3;
	  	    	  dfs(now+1);
	  	    	  f(k ,i ,j1) a[k]+=3;
	  	       }
   }
}
int main(){
	freopen("landlords.in","r",stdin);
	freopen("landlords.out","w",stdout);
	
	scanf("%d%d", &t, &n);
	f(k ,1 ,t){
		memset(a,0,sizeof(a));
		f(i ,1 ,n){
			int x,y;
			scanf("%d%d", &x, &y);
			if(x == 1) x=13;
			if(x!=0) x-=1;
			a[x]++;
		}
		ans=oo;
	    dfs(0);
	    printf("%d\n",ans);
	}
	return 0;
}

这周要把2sat 网络流看了 头疼

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值