zoukankan      html  css  js  c++  java
  • 江苏省赛 方格覆盖 题解

    给定一个 (n imes n) 的矩形,其中从左上角开始,对角线上连续的 (k) 个格子中有障碍物。你可以把若干 (1 imes2) 的小矩形放置到该大矩形中,要求是放置的两个小矩形不能占据相同的格子,且不能碰到障碍物。例如右图是 (n=1,k=2) 的例子,我们放置了 6 个 的小矩形。
    在这里插入图片描述
    给定 (n,k),请你输出一个方案,使得放置的 (1 imes2) 小矩形尽可能多。可以证明, (n=4,k=2) 时,至多只能放置 (6) 个小矩形。

    这题本质上就是一个贪心

    方法1:横着扫,然后竖着扫

    #include <bits/stdc++.h>
    using namespace std;
    int a[55][55],s;
    int main(){
        int n,k;
        cin>>n>>k;
        for(int i=1;i<=k;i++)a[i][i]=-1;//障碍的放置,从左上角开始
        for(int i=1;i<=n;i++)//逐行扫,查看是否能放横着的
        	for(int j=1;j<n;j++)
        		if(a[i][j]==0&&a[i][j+1]==0){//查看是否有地方放,如果有放
        			a[i][j]=++s;
        			a[i][j+1]=s;//标号
    			}
    	for(int j=1;j<=n;j++)//逐列扫,查看是否能放竖着的
    		for(int i=1;i<n;i++)
    			if(a[i][j]==0&&a[i+1][j]==0){//查看是否有地方放,如果有放
    				a[i][j]=++s;
    				a[i+1][j]=s;//标号
    			}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++)
    			if(a[i][j]==-1)cout<<0<<" ";
    			else cout<<a[i][j]<<" ";//随便用什么格式输出,不妨用一个空格输出
    		cout<<endl;
    	}
    	return 0;
    }
    /*
    至于这种简单的贪心的正确性
    考试时,我没有想到如何证明它是对的
    我们可以稍微感性的去想一想
    如果有剩余的格子
    你就要让剩余的格子放在一起,你可以去尝试一下,总是不能把剩余的格子放在一起
    */
    

    方法2:螺旋扫

    考试结束后,王星钱说他是用了螺旋扫的方法,这种方法很巧妙,显然易见它是对的,只是码量稍微的大了一点点

    先做一遍螺旋矩阵

    #include <bits/stdc++.h>
    using namespace std;
    int a[55][55],s,f,x,y;
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};
    int fx[4]={1,-1,-1,1};
    int main(){
        int n;
        cin>>n;
        int bonder[4]={1,n,n,1};
    	x=1,y=1;
    	for(int i=1;i<=n*n;i++){//n*n个格子
    		a[x][y]=i;
    		if(x+dx[f]<bonder[0]||y+dy[f]>bonder[1]||x+dx[f]>bonder[2]||y+dy[f]<bonder[3])bonder[f]+=fx[f],f=(f+1)%4;//进行螺旋
    		x+=dx[f],y+=dy[f];
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++)
    			cout<<a[i][j]<<" ";
    		cout<<endl;
    	}
    	return 0;
    }
    

    确保对了之后开始进行赋值

    #include <bits/stdc++.h>
    using namespace std;
    int a[55][55],s,f,x,y;
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};
    int fx[4]={1,-1,-1,1};
    int main(){
        int n,k;
        cin>>n>>k;
        int bonder[4]={1,n,n,1};
        for(int i=1;i<=k;i++)a[i][i]=-1;//障碍的放置,从左上角开始
    	x=1,y=1;//要这样写,否则会错k=0的点
    	for(int i=1;i<=n*n;i++){//n*n个格子
    		if(x+dx[f]<bonder[0]||y+dy[f]>bonder[1]||x+dx[f]>bonder[2]||y+dy[f]<bonder[3])bonder[f]+=fx[f],f=(f+1)%4;//进行螺旋
    		if(a[x][y]==0&&a[x+dx[f]][y+dy[f]]==0){//赋值
    			a[x][y]=++s;
    			a[x+dx[f]][y+dy[f]]=s;
    		}
    		x+=dx[f],y+=dy[f];
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++)
    			if(a[i][j]==-1)cout<<0<<" ";
    			else cout<<a[i][j]<<" ";//随便用什么格式输出,不妨用一个空格输出
    		cout<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    node实现将打包后的文件转压缩包
    Git/SVN忽略node_modules文件
    node实现发送邮件
    node搜索文件夹下的指定内容
    node批量修改文件文本内容
    微信小程序上线发布需要做的事情
    两件事 Jquery.form 锁
    .NET MVC 提交表单出现检测到有潜在危险的Request.Form值
    第一次使用TinyMCE
    第一次使用Entity Framework 的CodeFirst
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/13829948.html
Copyright © 2011-2022 走看看