今天考了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 网络流看了 头疼