2022.1.25

T1:走迷宫

可以写if,也可以用for循环配合二维数组
注意初始化 vis[1][1]=1
注意递归次数过多会导致MLE(奇怪的知识又增加了)

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdlib>
using namespace std;
int n,a[110][110],ans;
int b[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
bool vis[110][110];
void dfs(int x,int y,int t)
{
    for(int i=0;i<8;i++)//算符种类
    {
        if((!vis[x+b[i][0]][y+b[i][1]])&&(!a[x+b[i][0]][y+b[i][1]))//判重
            if(x+b[i][0]>=1&&x+b[i][0]<=n)
                if(y+b[i][1]>=1&&y+b[i][1]<=n)//边界  合法
                {
                    x+=b[i][0];
                    y+=b[i][1];
                    vis[x][y]=1;
                    if(x==1&&y==n)ans++;
                    else dfs(x,y,t+1);
                    vis[x][y]=0;
                    x-=b[i][0];
                    y-=b[i][1];
                }
    }
}
int main()
{
    vis[1][1]=1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    dfs(1,1,1);
    printf("%d",ans);
    return 0;
}
T2:团结地入伍

很像监狱那道题,几乎一样:先标记再判断,分选与不选两种情况
至于没一次AC?T1MLE阴影过深,数组只开到了30(居然也过了67分)
像在洛谷上水一波结果T掉了一个????

点击查看代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdlib>
using namespace std;
int book[110][110],n,m,a[110],vis;
int x[110],ans,ans1;//x作为a的过程,ans1作为ans的过程
void dfs(int k)
{
    if(k>n)//边界
    {
        if(ans1<=ans)return;//剪枝
        else ans=ans1;
        for(int i=1;i<=n;i++)
        {
            a[i]=x[i];
        }
        return;
    }
    vis=1;//选
    for(int i=1;i<k;i++)//不算自己
        if(book[i][k]&&x[i])
        {
            vis=0;
            break;//优化在这里
        }
    if(vis)
    {
        x[k]=1;
        ans1++;
        dfs(k+1);//
        ans1--;
        x[k]=0;
    }
    dfs(k+1);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        book[u][v]=1;
        book[v][u]=1;
    }
    dfs(1);
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
    {
        printf("%d ",a[i]);
    }
    return 0;
}
T3:最佳调度

果然带调度的题都很恶心。。。
三个优化一个不能少

  1. 若和已经大于minn剪掉y>=minn要带等
  2. 只有和加上后还小于才继续
  3. 主程序里要sort一次,目的是尽可能考前地剪掉和大的情况
点击查看代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
using namespace std;
int a[10010],m[10010],n,k,minn=1e6;
bool cmp(int aa,int bb){ return aa>bb; }
void dfs(int x,int y)
{
    if(y>=minn)return;
    if(x>n)
    {
        minn=min(y,minn);
        return;
    }
    for(int i=1;i<=k;i++)
    {
        if(m[i]+a[x]<=minn&&x<=n)
        {
            m[i]+=a[x];
            y=max(y,m[i]);
            dfs(x+1,y);
            m[i]-=a[x];
        }
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    dfs(1,0);
    printf("%d",minn);
    return 0;
}
T4:图的m着色问题

调的时候要注意前后一制,一开始写x++;后来改为for(int i=1;i<=n;i++)后要记得改回来

点击查看代码
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,k,ans,col[10010],e[110][110];
bool judge(int k,int i)
{
	for(int j=1;j<k;j++)
	{
		if(e[j][k]==1&&col[j]==i)return false;
	}
	return true;
}
void search(int k,int x)
{
	if(k>n)ans++;
	else for(int i=1;i<=x;i++)
	{
		if(judge(k,i))
		{
			col[k]=i;;
			search(k+1,x);
		}
	}
}
int main()
{
	scanf("%d%d%d",&n,&k,&m);
	for(int i=1;i<=k;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		e[u][v]=1;
		e[v][u]=1;
	}
	search(1,m);
	printf("%d",ans);
	return 0;
}
posted @ 2022-01-25 15:38  fervency  阅读(20)  评论(0编辑  收藏  举报