2021-01-28

2021年1月27日

早上6点起床打卡
然后睡觉睡到下午 也不晓得几点了
解昨天决残留下来的的问题

N皇后问题

在这里插入图片描述
这个题我实在优化不了时间了
于是就打表大法了
搜索代码

#include<stdio.h>
#include<string.h>
#include<math.h>
int n;
int count=0;
int book[11];//用桶的思想来表示是不是用过 就可以省去了一个On的循环
int dfs(int step)
{
	if(step==n+1)
	{
		count++;
		return 0;
	 } 
	 int x=step;
	for(int i=1;i<=n;i++)
	{	
		if(step==1)
		{
			book[step]=i;
			dfs(step+1);
		}
		else 
		{
			int flag=0;
			for(int j=1;j<step;j++)
			{
				if(j+book[j]==step+i||j-book[j]==step-i||i==book[j])flag=1;
				//左斜上45°就是一个y=-x+b的函数 所以s+y=b
				//右斜上45°就是一个y=x+b的函数 所以y-x=b
			}
			if(flag==0)
			{
				book[step]=i;
				dfs(step+1);
			}
		}
	}
	return 0; 
}
int main()
{
	while(~scanf("%d",&n))
	{
		if(n==0)break;
		memset(book,0,sizeof(book));
		count=0;
		dfs(1);
		printf("%d\n",count);
	}
	return 0;
 } 

正真的ac代码

#include<stdio.h>
int main()
{
	int a[11]={0,1,0,0,2,10,4,40,92,352,724};
	int n;
	while(~scanf("%d",&n))
	{
		if(n==0)break;
		else printf("%d\n",a[n]);
	}
}

E - 棋盘问题

在这里插入图片描述
这个问题看似和上面N皇后有点像 其实暗藏玄机
棋盘要是可以选 我也可以不选啊
就是说这一行要是有#就是说可以放下一个棋子 让num+1 我也选择不放 让num不+1 然后让后面几行就有得选了
所以一开始卡了很久

#include<stdio.h>
int n;
int k;
char map[10][10]; 
int book[10];//列坐标记录  运用桶的思想 
int count=0;
int dfs(int step,int num)
{
		if(num==k+1)
	{
		count++;
		return 0;
	}
	if(step==n+1)return 0;

	for(int i=1;i<=n;i++)
	{
	
		if(book[i]==0&&map[step][i]=='#')
		{	
			book[i]=1;
			dfs(step+1,num+1);
			book[i]=0;
		}
	
	}
	dfs(step+1,num);//此行就是放和不放2种 假如可以放   在上面循环放入棋子的都列举出来了 
}					//但是我们也选择不发尽管他可以放  
int main()
{
  while(~scanf("%d%d",&n,&k))  
{
  	if(n==k&&k==-1)break;
  	for(int i=1;i<=n;i++)
  	{
  		scanf("%s",&map[i][1]);
	  }
	  count=0;
	  dfs(1,1);
	  printf("%d\n",count);
}
    
    return 0;
}

K - Prime Path

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices.
— It is a matter of security to change such things every now and then, to keep the enemy in the dark.
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know!
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door.
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime!
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds.
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime.
Now, the minister of finance, who had been eavesdropping, intervened.
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound.
— Hmm, in that case I need a computer program to minimize the cost. You don’t know some very cheap software gurus, do you?
— In fact, I do. You see, there is this programming contest going on… Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above.
1033
1733
3733
3739
3779
8779
8179
The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.
Input
One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).
Output
One line for each case, either with a number stating the minimal cost or containing the word Impossible.
Sample Input
3
1033 8179
1373 8017
1033 1033
Sample Output
6
7
0

上面这个题就我来翻译翻译吧
输入 t
然后有t组数据
每组数组2个
位两个质数
然后第一个质数最少几步可以变成第二个质数
变换规则是 个位 十位 百位 千位都可以变但是只能变一个数字
变换后的数字 继续变 直到变成了 第二个数据

例如
1033//百位变成7 一步
1733//千位变成3 两步
3733//个位变成9 三步
3739//十位变成7 四步
3779//千位变成8 五步
8779//百位变成1 六步
8179//变好了6步
这个题 我慢慢讲
我们要把一个数变为另外一个数
例如1033
那么我们有很多个变法
我们可以改变千位1到9任意选择
也可以改变百位,十位,个位0到9任意选择
然后要求是素数 那么我们把这个数全部可以改变的情况都列举出来
然后判断是不是素数 然后存起来
也就是1033的所有可以变为是素数存起来
然后再从这个变出来的数据 再变出来 数据
一直变一直变 知道出现 我们的第二个数据k出现了就 停止
数一数变了几遍就ok了
那么很明显就是bfs

要用质数 所以我先预处理一个素数表 便于判断

int book[10000];//素数表 
	for(int i=2;i<10000;i++)
	{
		if(book[i]==0)
		{
			for(int j=i*2;j<10000;j+=i)
			{
				book[j]=1;
			}
		}
	}
伪代码
{
while(只要可以变出来数据来)
{
列举出来所有可以变得数据 判断是不是素数
然后判断 是不是k 是k就结束
}

}

ac代码

#include<stdio.h>
#include<string.h>
int ans[10000000][3];
int book[10000];//素数表 
int bo[10000];
int main()
{
	int t;
	for(int i=2;i<10000;i++)
	{
		if(book[i]==0)
		{
			for(int j=i*2;j<10000;j+=i)
			{
				book[j]=1;
			}
		}
	}
	scanf("%d",&t);
	while(t--)
	{	
		memset(bo,0,sizeof(bo));
		int tail=0;
		int head=0;
		int n;
		int k;
		scanf("%d%d",&n,&k);
		ans[tail][0]=n;
		ans[tail++][1]=0;
		int count=0;
		if(book[k]==1||k<=1000||k>=10000)printf("Impossible\n");
		else
		while(head<=tail)
		{
			bo[ans[head][0]]=1;
			int flag=0;
			if(ans[head][0]==k)break;
			for(int i=1;i<=9;i++)
			{
				int temp=ans[head][0];
				int a=temp%10;
				temp=temp/10;
				int b=temp%10; 
				temp=temp/10;
				int c=temp%10; 
				temp=temp/10;
				int d=temp%10; 
				int end=i*1000+c*100+b*10+a; 
				if(bo[end])continue;
				else if(book[end]==0)
				{
					ans[tail][0]=end;
					ans[tail][2]=head;
					ans[tail++][1]=ans[head][1]+1;
					bo[end]=1;
					if(end==k)
				{
					flag=1;
					break;
				}
				}
			}
			if(!flag)for(int i=0;i<=9;i++) 
			{
					int temp=ans[head][0];
				int a=temp%10;
				temp=temp/10;
				int b=temp%10; 
				temp=temp/10;
				int c=temp%10; 
				temp=temp/10;
				int d=temp%10; 
				int end=i*100+a+b*10+d*1000; 
					if(bo[end])continue;
				else if(book[end]==0)
				{
					ans[tail][0]=end;
					ans[tail][2]=head;
					ans[tail++][1]=ans[head][1]+1;
					bo[end]=1;
					if(end==k)
				{
					flag=1;
					break;
				}
				}
			}
			if(!flag)for(int i=0;i<=9;i++)
			{
					int temp=ans[head][0];
				int a=temp%10;
				temp=temp/10;
				int b=temp%10; 
				temp=temp/10;
				int c=temp%10; 
				temp=temp/10;
				int d=temp%10; 
				int end=i*10+a+c*100+d*1000; 
					if(bo[end])continue;
				else if(book[end]==0)
				{
					ans[tail][0]=end;
					ans[tail][2]=head;
					ans[tail++][1]=ans[head][1]+1;
					bo[end]=1;
					if(end==k)
				{
					flag=1;
					break;
				}
				}
			}
			if(!flag)for(int i=0;i<=9;i++)
			{
				int temp=ans[head][0];
				int a=temp%10;
				temp=temp/10;
				int b=temp%10; 
				temp=temp/10;
				int c=temp%10; 
				temp=temp/10;
				int d=temp%10; 
				int end=i+d*1000+b*10+c*100; 
					if(bo[end])continue;			
				else if(book[end]==0)
				{
					ans[tail][0]=end;
					ans[tail][2]=head;
					ans[tail++][1]=ans[head][1]+1;
					bo[end]=1;
					if(end==k)
				{
					flag=1;
					break;
				}
				}
			}
			if(flag==1)break;
			head++;
		 } 
		 if(head<=tail)printf("%d\n",ans[tail-1][1]); 
		 else printf("Impossible\n");
	//	 for(int i=tail-1;i>=0;i=ans[i][2])
	//	 {
	//	 	printf("%d---",ans[i][0]);
	//	 	if(i==0)break;
		 	
//	}
//	 printf("\n");
	}
 } 

bfs运用队列 具体就不讲了 因为我也阐述不清楚 呜呜呜
这里说明一下 ans【i】【0】代表数据
ans【i】【1】代表步数
ans【i】【2】代表由哪个数变出来的下标
最后注释的代码是打印变化的由来 也就是ans【i】【2】的作用了在这里没有用book数组是素数表bo数组是表示变过的数 防止重复的数据再变(盲猜 可能死循环)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值