这er天,大多在做搜索题组,java学到了接口和包的部分了
思路:一道求连通块的题,每找到一块未被标记的要塞,计数并八个方向进行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);
}}
思路:根据题意,将拼接的字符串分为俩部分,每部分轮流取一个组成新字符串。
于是可以用字符串函数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;} //循环一轮未找到
}
}
}
思路:这题用搜索加二进制枚举来做,因为根据第一行的反转情况,就能确定总体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;
}