2017.10.28 C组比赛总结

这次比赛有点坑。。。


【GDKOI2004】石子游戏

方法:判断奇偶性

  1. 输入n
  2. 如果n是奇数,输出 xiaoshi
  3. 如果n是偶数,输出 xiaoyong

比赛得分:30
错因:找错规律了(忘记了两个人都是聪明绝顶滴)


【GDKOI2004】汉诺塔

方法1:找规律

1.定义一个数组a 赋值为 1,2,3,3,2,1
2.输入N和M
3.定义一个变量k,初始化为1。
4.从1到N循环,输出a[ ( M mod 6K ) div K ],K每次×3。

方法2:暴力
▒​▓░▒​我░​▓不░▒​▓░会​▓░▒​打▒​▓░

比赛得分:30
一个点答案错误,剩余的点时间超限


【GDKOI2004】城市统计

方法: BFS+前缀和

先用BFS求出每一个地方离最近的商业区的距离。
然后求个前缀和。
最后枚举每个点(i,j),算出从(i-r,j-r)到(i+r,j+r)的所有地方的距离和,并输出
注意判断边界(小心i-r,j-r小于0,或i+r,j+r大于0)
比赛得分:0
错因:没判断好边界。


【GDKOI2004】香樟树

方法: DP
比赛时我就想出正解了,可惜……细节决定成败!!!
先求出2到100000之间所有的质数,用一个数组s存着。
设 a[i] 表示第i棵树的叶子个数
设 f[i] 表示到第 i 棵树的最多树的数量。
设 g[i] 为最大的f[有 s[i] 这个质因数的树的编号]。
那么 f[i]=max (g[a[i]的质因数]) +1,最后再用f[i]来更新g[a[i]的质因数]的值。
再加上一点小优化就能AC了。
比赛得分:10
错因: 时间超限了 (%#@#$%…)


【提高组NOIP2008】双栈排序

方法:二分图染色
此题有点难。
https://www.cnblogs.com/huangzihaoal/p/11154097.html ←__←题解在这里
比赛得分:27.3


代码

第一题

#include<cstdio>
using namespace std;
int main()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	int c,n;
	scanf("%d",&c);
	while(c--)
	{
		scanf("%d",&n);
		if(n%2) puts("xiaoshi");
		else puts("xiaoyong");
	}
	return 0;
}

第二题

#include<cstdio>
using namespace std;
const int a[6]={1,2,3,3,2,1};
int main()
{
	freopen("hanoi.in","r",stdin);
	freopen("hanoi.out","w",stdout);
	int t,i,k,n,m;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		k=1;
		for(i=1;i<n;i++)
		{
			printf("%d ",a[(m%(k*6))/k]);
			k=k*3;
		}
		printf("%d\n",a[(m%(k*6))/k]);
	}
	return 0;
}

第三题

#include<cstdio>
using namespace std;
#define maxlongint 0x7fffffff
int n;
bool map[151][151];
int dis[151][151],f[151][151],date[23000][2],g[151][151];
const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
void bfs(int x,int y)
{
	int head=0,tail=1,tx,ty,xx,yy,i;
	date[1][0]=x,date[1][1]=y;
	while(head<tail)
	{
		head++;
		tx=date[head][0],ty=date[head][1];
		for(i=0;i<4;i++)
		{
			xx=tx+dx[i],yy=ty+dy[i];
			if(xx>0&&yy>0&&xx<=n&&yy<=n&&dis[tx][ty]+1<dis[xx][yy])
			{
				tail++;
				date[tail][0]=xx,date[tail][1]=yy;
				dis[xx][yy]=dis[tx][ty]+1;
			}
		}
	}
}
int main()
{
	freopen("city.in","r",stdin);
	freopen("city.out","w",stdout);
	int i,j,k,x,y,xx,yy,tt;
	scanf("%d",&tt);
	while(tt--)
	{
		scanf("%d%d",&n,&k);
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				scanf("%d",&map[i][j]);
				if(map[i][j]) dis[i][j]=0;
				else dis[i][j]=maxlongint;
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++) if(map[i][j])
			{
				bfs(i,j);
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+dis[i][j];
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(i-k>0) x=i-k;
				else x=1;
				if(j-k>0) y=j-k;
				else y=1;
				if(i+k<=n) xx=i+k;
				else xx=n;
				if(j+k<=n) yy=j+k;
				else yy=n;
				g[i][j]=f[xx][yy]-f[xx][y-1]-f[x-1][yy]+f[x-1][y-1];
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<n;j++)
			{
				printf("%d ",g[i][j]);
			}
			printf("%d\n",g[i][n]);
		}
		printf("\n");
	}
	return 0;
}

第四题

#include<cstdio>
#include<cmath>
using namespace std;
int num,f[100001],g[10001],sum[10001],b[7];
bool pd(int x)//判断质数
{
	int i,tt=sqrt(x);
	for(i=2;i<=tt;i++)
	{
		if(x%i==0) return 0;
	}
	return 1;
}
int main()
{
	freopen("camphor.in","r",stdin);
	freopen("camphor.out","w",stdout);
	int n,i,j,ans=0,k,a;
	scanf("%d",&n);
	for(i=2;i<=100000;i++)
	{
		if(pd(i))
		{
			sum[++num]=i;
		}
	}
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a);
		b[0]=0;
		for(j=1;j<=num;j++)
		{
			if(a<sum[j]) break;
			if(a%sum[j]==0)
			{
				b[++b[0]]=j;
				if(g[j]>f[i]) f[i]=g[j];
				while(a%sum[j]==0) a=a/sum[j];
			}
		}
		f[i]=f[i]+1;
		if(f[i]>ans) ans=f[i];
		for(j=1;j<=b[0];j++)
		{
			if(g[b[j]]<f[i]) g[b[j]]=f[i];
		}
	}
	printf("%d\n",ans);
	return 0;
}

第五题

#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAX 0x7fffffff
int s[1010],f[1010],c[1010],a[1010],b[1010],edge[1010][1001];
char st[5010];bool bk[1010];
void inc(int x,int y)
{
	edge[x][++edge[x][0]]=y;
	edge[y][++edge[y][0]]=x;
}
void build(int k)
{
	if(bk[k]) return;
	bk[k]=true;
	if(c[k]==0) c[k]=1;
	int i,j;
	for(i=1;i<=edge[k][0];i++)
	{
		j=edge[k][i];
		if(c[k]==c[j])
		{
			puts("0");
			exit(0);
		}
		if(c[k]==1) c[j]=2;
		else c[j]=1;
		build(j);
	}
}
int main()
{
	freopen("twostack.in","r",stdin);
	freopen("twostack.out","w",stdout);
	int n,i,j,k,ans=0,next=1;
	scanf("%d",&n);
	f[n+1]=MAX;
	for(i=1;i<=n;i++) scanf("%d",&s[i]);
	for(i=n;i>0;i--)
	{
		if(s[i]>f[i+1]) f[i]=f[i+1];
		else f[i]=s[i];
	}
	for(i=1;i<n;i++)
	{
		for(j=i+1;j<n;j++)
		{
			if(s[i]<s[j]&&s[i]>f[j+1])
			{
				inc(i,j);//连边
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		build(i);//染色部分
	}
	for(i=1;i<=n;i++)
	{
		if(c[i]==1)
		{
			st[++ans]='a';
			++a[0];
			a[a[0]]=s[i];
		}
		else
		{
			st[++ans]='c';++b[0];
			b[b[0]]=s[i];
		}
		while(a[a[0]]==next)
		{
			st[++ans]='b';
			next++;a[0]--;
		}
		while(b[b[0]]==next)
		{
			if(i<n&&(a[0]==0||(c[i+1]==1&&a[a[0]]>s[i+1])))
			{
				i++;++a[0];
				a[a[0]]=s[i];
				st[++ans]='a';
			}
			st[++ans]='d';
			next++;b[0]--;
		}
		while(a[a[0]]==next)
		{
			st[++ans]='b';
			next++;a[0]--;
		}
	}
	while(a[0]>0||b[0]>0)
	{
		while(a[a[0]]==next)
		{
			st[++ans]='b';
			next++,a[0]--;
		}
		while(b[b[0]]==next)
		{
			st[++ans]='d';
			next++,b[0]--;
		}
	}
	for(i=1;i<ans;i++) printf("%c ",st[i]);
	printf("%c\n",st[ans]);
	return 0;
}
posted @ 2019-07-08 21:57  Alexander_菜鸡  阅读(178)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end