最近打比赛发现了自己很多问题,基础一点都不牢靠,很多显而易见的问题都发现不了,所以重新刷专题。
hdu 1241 戳这里
求最大连通块的问题 这种 迷宫类型的题目 现在真是直接就能敲。
#include <cstdio>
#include <map>
#include <iostream>
#include<bits/stdc++.h>
#define N 20000000
#define ll long long int
using namespace std;
char map1[105][105];
int vis[105][105];
int dir[8][2]={1,0,-1,0,0,-1,0,1,1,1,1,-1,-1,1,-1,-1};
int n,m,num=0;
bool jg(int x,int y)
{
for(int i=0;i<8;i++){
int x1=x+dir[i][0];
int y1=y+dir[i][1];
if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&map1[x1][y1]=='@'&&!vis[x1][y1])
return true;
}
return false;
}
void dfs(int x,int y)
{ //cout<<x<<" "<<y<<" "<<num<<endl;
if(!jg(x,y))
{
return ;
}
for(int i=0;i<8;i++){
int x1=x+dir[i][0];
int y1=y+dir[i][1];
if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&map1[x1][y1]=='@'&&!vis[x1][y1]){
vis[x1][y1]=1;
dfs(x1,y1);
// vis[x1][y1]=0;
}
}
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{ if(n==0&&m==0)
break;
memset(vis,0,sizeof(vis));
num=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>map1[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(map1[i][j]=='@'&&!vis[i][j]){
vis[i][j]=1;
dfs(i,j);
num++;
}
}
cout<<num<<endl;
}
}
hdu 1584 戳这里
题面很好懂,一开始也以为是一道大水题,但是后面越想越复杂,想不通怎么去遍历所有情况,只能说水平还是不够,看了很多题解,总结了一下。
解法一:标准的搜索结构,搜索方法无非就是把1->2 2->3…9->10 共有9种情况,每次执行一种情况就修改牌所在的位置,代码的关键我感觉就是回溯的那两次循环,想通以后思路还是很简单的,但是好像比较慢。
#include <cstdio>
#include <map>
#include <iostream>
#include<bits/stdc++.h>
#define N 20000000
#define ll long long int
using namespace std;
int pos[11];
int vis[11];
int mind=0x3f3f3f3f;
void dfs(int step,int k)
{ int c[11];
memset(c,0,sizeof(c));
if(step==9){
//cout<<k<<endl;
if(mind>k)
mind=k;
return ;
}
for(int i=1;i<=9;i++){
if(!vis[i]){
vis[i]=1;
int kk=k+abs(pos[i+1]-pos[i]);
//cout<<kk<<endl;
int temp=pos[i];
for(int j=1;j<=10;j++){
if(pos[j]==temp){
pos[j]=pos[i+1];
c[j]=temp;
}
}
dfs(step+1,kk);
vis[i]=0;
for(int j=1;j<=10;j++){
if(c[j]==temp)
pos[j]=temp;
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{ memset(vis,0,sizeof(vis));
for(int i=1;i<=10;i++){
int x;
cin>>x;
pos[x]=i;
}
mind=0x3f3f3f3f;
dfs(0,0);
cout<<mind<<endl;
}
}
解法二:这种解法就是二重循环去搜索i->j的所有情况。其实我更倾向于这种做法。。
#include <cstdio>
#include <map>
#include <iostream>
#include<bits/stdc++.h>
#define N 20000000
#define ll long long int
using namespace std;
int pos[11];
int vis[11];
int mind=0x3f3f3f3f;
void dfs(int step,int k)
{ if(k>mind)
return ;
if(step==9){
//cout<<k<<endl;
if(mind>k)
mind=k;
return ;
}
for(int i=1;i<10;i++){
if(!vis[i]){
vis[i]=1;
for(int j=i+1;j<=10;j++){
if(!vis[j]){
dfs(step+1,k+abs(pos[i]-pos[j]));
break;
}
}
vis[i]=0;
}
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{ memset(vis,0,sizeof(vis));
for(int i=1;i<=10;i++){
int x;
cin>>x;
pos[x]=i;
}
mind=0x3f3f3f3f;
dfs(0,0);
cout<<mind<<endl;
}
}
#include <cstdio>
#include <map>
#include <iostream>
#include<cstring>
#define N 20000000
#define ll long long int
using namespace std;
int n,m,q;
int map1[1005][1005];
int vis[1005][1005];
int dir[4][2]={1,0,-1,0,0,-1,0,1};
int x1,x2,y1,y2;
int dfs(int x,int y,int wan,int direct)
{ //cout<<wan<<endl;
if(wan>2)
return 0;
if(x==x2&&y==y2)
return 1;
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&(!map1[tx][ty]||(tx==x2&&ty==y2))&&!vis[tx][ty]){
vis[tx][ty]=1;
if(direct==i){
if(dfs(tx,ty,wan,direct))
return 1;
}
else{
if(dfs(tx,ty,wan+1,i))
return 1;
}
vis[tx][ty]=0;
}
}
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0)
break;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&map1[i][j]);
scanf("%d",&q);
for(int i=1;i<=q;i++){
memset(vis,0,sizeof(vis));
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
vis[x1][y1]=1;
if((map1[x1][y1]!=map1[x2][y2])||map1[x1][y1]==0){
printf("NO\n");
continue;
}
if(dfs(x1,y1,-1,-1))
printf("YES\n");
else
printf("NO\n");
}
}
}