四之结(3.16)

这er天,大多在做搜索题组,java学到了接口和包的部分了

z简单搜索&&进阶搜索 - Virtual Judge

思路:一道求连通块的题,每找到一块未被标记的要塞,计数并八个方向进行dfs,标记所有连在一起的要塞,

最后统计结果就ok了

 

#include<iostream>
#include<cstdio>
using namespace std;
char a[105][105];
int book[105][105]={0};
int dx[8]={0,0,1,1,1,-1,-1,-1};
int dy[8]={1,-1,0,-1,1,0,-1,1};
int n,m,sum;
void dfs(int x,int y)
{
    book[x][y]=1;
    for(int i=0;i<8;i++){      //向八个方向搜索
         int fx=x+dx[i];
        int fy=y+dy[i];
        if(fx<=0||fx>n||fy<=0||fy>m){continue;}
        if(a[fx][fy]=='@'&&book[fx][fy]==0)
        dfs(fx,fy);
    }
}

int main()
{
    int T=100000;
    while(T--){
        scanf("%d %d",&n,&m);
        getchar();
        sum=0;
        if(n==0)break;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%c",&a[i][j]); //输入
                book[i][j]=0; //清除上轮标记
            }getchar();
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                    if(a[i][j]=='@'&&book[i][j]==0){sum++;dfs(i,j);}
    }
}
printf("%d\n",sum);


}}

简单搜索&&进阶搜索 - Virtual Judge

思路:根据题意,将拼接的字符串分为俩部分,每部分轮流取一个组成新字符串。

于是可以用字符串函数strcpy--复制原来的串来形成新串

strcmy--判断是否循环一轮未果或找到目标字符串

来做,用循环的次数作为编号

 

#include<stdio.h>
#include<string.h>
char s1[205],s2[205],s[205],s3[205],sk[205],ss[205];//s为要变的字符串,ss为求字符串,sk为旧的字符串
int n;
int main()
{
    int T,i,j;
    scanf("%d",&T);
for(int l=1;l<=T;l++){
    scanf("%d",&n);
    getchar();
    scanf("%s",s1);
    scanf("%s",s2);
    scanf("%s",s3);
   for(i=0,j=0;i<n;i++){
    s[j++]=s2[i];
    s[j++]=s1[i];
   }
   s[j]=0;
   strcpy(ss,s);
   int t=0;
   while(++t){
       if(strcmp(s,s3)==0){printf("%d %d\n",l,t);break;} //变换后找到要求字符串
        strcpy(sk,s);
   for(int i=0,j=0;i<n;i++){ //生成下一个字符串
    s[j++]=sk[i+n];
    s[j++]=sk[i];
   }s[j]=0;
    if(strcmp(s,ss)==0){printf("%d -1\n",l);break;} //循环一轮未找到


   }
}
}

简单搜索&&进阶搜索 - Virtual Judge

思路:这题用搜索加二进制枚举来做,因为根据第一行的反转情况,就能确定总体1的反转情况,所有对第一行进行枚举,用最后一行是否达成条件判断这轮枚举是否成立.最后找出字典序最小的那种情况输出

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int inf = 111111111;
int n,m;
int mp[20][20];//初始
int tmp[20][20];//当前
int ans[20][20];//最优
int fx[5][2] = { {0,1},{1,0},{-1,0},{0,-1},{0,0} };
//判断
int f(int x, int y) {
	int cnt = mp[x][y];
	for (int i = 0; i < 5; ++i) {
		int dx = fx[i][0] + x; int dy = fx[i][1] + y;
		if (dx >= 0 && dx < n && dy >= 0 && dy < m)
			cnt += tmp[dx][dy];
	}
	return cnt % 2;
}
int solve() {
	int cnt = 0;
	for (int i = 1; i < n; ++i) {  //第二行开始判断
		for (int j = 0; j < m; ++j) {
			if (f(i - 1, j))tmp[i][j] = 1;
		}
	}
	for (int i = 0; i < m; ++i) {   //判断末行是否为0
		if (f(n - 1, i))return inf;
	}
	for (int i = 0; i < n; ++i) {   //统计翻转数
		for (int j = 0; j < m; ++j) {
			cnt += tmp[i][j];
		}
	}
	return cnt;
}
int main(void)
{
	int num =inf;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			scanf("%d", &mp[i][j]);
		}
	}
	for (int i = 0; i < (1 << m); ++i) {
		for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j) tmp[i][j]=0;
		for (int j = 0; j < m; ++j)
			tmp[0][j] = i >> j & 1;
		int sum = solve();
		if (sum < num) {
			num = sum;
			for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j) ans[i][j]=tmp[i][j];
		}
	}
	if (num ==inf)printf("IMPOSSIBLE\n");
	else {
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				printf("%d ", ans[i][j]);
			}printf("\n");
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值