关于OI题库t3
查看原帖
关于OI题库t3
222578
jingkongwanglimiaoa楼主2020/8/29 17:45

题目点

一看到这一题,蒟蒻就想到了爆搜

非常明显蒟蒻连爆搜都做不对

代码如下

# include <cstdio>
# include <cstring>
using namespace std;
int e[1010][1010],dx[4] = {0,0,-1,1},dy[4] = {1,-1,0,0},minn,p,q,n,m,k,aa,bb,ans = 0,a,b,f[1010][1010];//e数组是矩阵,dxdy表示方向,minn用来存储最少变色数,f数组标记有没有走过 
void dfs(int yy,int xx,int ccnt)
{
	if (f[yy][xx]) return ;//走过就return 
	if (yy == aa && xx == bb)//走到目标点 
	{
		if (ccnt < minn) minn = ccnt;
		return ;
	}
	for (int i = 0;i < 4;i++)
	{
		if (yy + dy[i] >= 1 && yy + dy[i] <= n && xx + dx[i] >= 1 && xx + dx[i] <= m)//不能越过边界 
		{
			f[yy][xx] = 1;//标记 
			if (e[yy][xx] != e[yy + dy[i]][xx + dx[i]])
			dfs(yy + dy[i],xx + dx[i],ccnt+1);
			else dfs(yy + dy[i],xx + dx[i],ccnt);
		}
	}
	a = yy;//新的起点 
	b = xx;
}
int main()
{
	scanf("%d %d %d %d %d",&n,&m,&k,&p,&q);
	for (int i = 1;i <= n;i++)
		for (int j = 1;j <= m;j++)
			scanf("%d",&e[i][j]);
	scanf("%d %d",&a,&b);
	for (int i = 1;i <= k;i++)
	{
		minn = 0x3f3f3f3f;
		aa = (i * p + q) % n + 1;
		bb = (i * q + p) % m + 1;
		dfs(a,b,0);
		ans = ans ^ minn;
	}
	printf("%d",ans);
}

代码并不是重点,大体没有问题

但有一个地方困扰了蒟蒻很久

就是它会死循环

原因:当一个点往它下面跑时,下一个点又会往上面跑,然后反复横跳

蒟蒻天真的以为做个记忆化就没事了(就是那个f数组),走过的点不能再走,时间紧张用脚造了一个弱样例就直接交了,一看结果0分

后来想一想这样子做一点道理也没有

这种情况到底怎么解决

或者要用别的算法?

2020/8/29 17:45
加载中...