topoi1305

文章前食用:本蒟蒻有一个坏习惯 会写read 然后就是max min abs会手打QAQ(所以当然不可能手打快排)当然你们可以理解学习我的写法(这种写法纯属偷懒

A CSU1460

思路:本题思路两种

思路1:用DFS 记忆化搜索 不走相同的路 看看能不能到终点

思路2:图论 这要是放在图论算是水题了 重点:把1000距离以内的当做一条边

然后用Floyd 去判断两点之间有没有路

下面是你们喜欢的代码QAQ

DFS

#include <bits/stdc++.h>
#define f(i,j,n) for(register int i=j;i<=n;i++)
using namespace std;
typedef long long ll;
inline ll read() {
    ll x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch-48),ch=getchar();
    return x*f;
}
int n;
int xa,ya,xb,yb;
struct node {
    int x,y;
} a[100+5];
bool vis[100+5];
bool flag=false;
inline ll Abs(ll x) {
    return x>0?x:-x;
}
inline void dfs(int x,int y) {
    if(Abs(xb-x)+Abs(yb-y)<=1000) {
        flag=true;
        return;
    }
    f(i,1,n)
    if(Abs(a[i].x-x)+Abs(a[i].y-y)<=1000 and!vis[i])
        vis[i]=true,dfs(a[i].x,a[i].y);
}
int main() {
    int t=read();
    while(t--) {
        flag=false;
        memset(a,0,sizeof(a));
        memset(vis,false,sizeof(vis));
        n=read();
        xa=read(),ya=read();
        f(i,1,n) a[i].x=read(),a[i].y=read();
        xb=read(),yb=read();
        dfs(xa,ya);
        flag?puts("win"):puts("lose");
    }
    return 0;
}

 Floyd

#include<bits/stdc++.h>
#define f(i,j,n) for(register int i=j;i<=n;i++)
using namespace std;
typedef long long ll;
inline ll read() {
    ll x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch-48),ch=getchar();
    return x*f;
}
struct node {
    int x,y;
} a[100+5];
bool f[100+5][100+5];
inline int Abs(int x) {
    return x>0?x:-x;
}
inline int qaq(node x,node y) {
    return Abs(x.x-y.x)+Abs(x.y-y.y);
}
int main() {
    int t=read();
    while(t--) {
        memset(a,0,sizeof(a)),memset(f,false,sizeof(f));
        int n=read()+2;
        f(i,1,n) a[i].x=read(),a[i].y=read();
        f(i,1,n-1) f(j,i+1,n) if(qaq(a[i],a[j])<=1000) f[i][j]=f[j][i]=true;
        f(k,1,n) f(i,1,n) if(i!=k) f(j,1,n) if(f[i][k] and f[k][j]) f[i][j]=true;
        if(f[1][n]) puts("win");
        else puts("lose");
    }
    return 0;
}

B HDU4499改编

思路:

(1)A和B在棋盘的同一行或同一列中;
(2)A和B之间有且只有一个其它棋子。

判断当前行和当前列能不能放棋子QAQ 码量有点大 可以复制一大段稍微改一下QAQ

DFS

#include <bits/stdc++.h>
#define f(i,j,n) for(register int i=j;i<=n;i++)
using namespace std;
typedef long long ll;
using namespace std;
inline ll read() {
    ll x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch-48),ch=getchar();
    return x*f;
}
int ans,n,m,q,T;
int vis[1<<4][1<<4];
inline int Max(int x,int y) {
    return x>y?x:y;
}
inline bool check(int a,int b) {
    register int flat=0,i,j;
    for(i=a-1; i>=1; i--) if(vis[i][b]) break;
    for(j=i-1; j>=1; j--) if(vis[j][b]==1) break;
        else if(vis[j][b]==2) {
            flat=1;
            break;
        }
    if(flat) return false;
    for(i=b-1; i>=1; i--) if(vis[a][i]) break;
    for(j=i-1; j>=1; j--) if(vis[a][j]==1) break;
        else if(vis[a][j]==2) {
            flat=1;
            break;
        }
    if(flat) return false;
    return true;
}
inline void dfs(int x,int y,int cnt) {
    if(x==n and y==m+1) {
        ans=Max(ans,cnt);
        return;
    }
    if(y==m+1) {
        dfs(x+1,1,cnt);
        return;
    }
    if(vis[x][y]) {
        dfs(x,y+1,cnt);
        return;
    }
    dfs(x,y+1,cnt);
    if(check(x,y)) vis[x][y]=2,dfs(x,y+1,cnt+1),vis[x][y]=0;
}
int main() {
    T=read();
    while(T--) {
        ans=0;
        memset(vis,false,sizeof(vis));
        n=read(),m=read(),q=read();
        f(i,1,q) {
            int x=read(),y=read();
            vis[x+1][y+1]=1;
        }
        dfs(1,1,0);
        cout<<ans<<endl;
    }
    return 0;
}

C Michigan Invitational Programming Competition October 9,2011

思路:从最大的面积开始 如果满足条件更新 加上check 每次搜索时带上一个check函数来判断范围内有没有蓝点(不应该判断区间 应该从点的下标开始) 由此 应该把红点 放在a数组 蓝点放在b数组 做b的循环 因为n<=20 所以b一定<=20 所以时间复杂度不高 但是如果判断区间 应该就是每次2000*2000=40000000 也就是说 每个点都会超时(除非数据水) 见代码QAQ

DFS

#include <bits/stdc++.h>
#define f(i,j,n) for(register int i=j;i<=n;i++)
using namespace std;
typedef long long ll;
typedef unsigned int uint;
const int inf=0x7f7f7f7f;
inline ll read() {
    ll x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch-48),ch=getchar();
    return x*f;
}
int n,cnt1,cnt2,ans=inf;
struct node {
    int x,y;
};
node a[1<<6],b[1<<6];
template<typename t>inline t Max(t x,t y) {
    return x>y?x:y;
}
template<typename t>inline t Min(t x,t y) {
    return x<y?x:y;
}
inline bool check(int x,int xx,int y,int yy) {
    f(i,0,cnt2-1) if(b[i].x<=x and b[i].x>=xx and b[i].y<=y and b[i].y>=yy) return false;
    return true;
}
inline void dfs(int t,int pre,int xmax,int xmin,int ymax,int ymin) {
    if(t>=(cnt1/2)) {
        if(check(xmax,xmin,ymax,ymin)) ans=Min(ans,(xmax-xmin)*(ymax-ymin));
        return;
    }
    f(i,pre+1,cnt1-1) dfs(t+1,i,Max(a[i].x,xmax),Min(xmin,a[i].x),Max(ymax,a[i].y),Min(ymin,a[i].y));
}
int main() {
    n=read(),ans=inf,cnt1=0,cnt2=0;
    f(i,1,n) {
        int x=read(),y=read(),z=read();
        if(z==0)a[cnt1].x=x,a[cnt1].y=y,cnt1++;
        else b[cnt2].x=x,b[cnt2].y=y,cnt2++;
    }
    dfs(0,-1,-inf,inf,-inf,inf);
    ans==inf?puts("-1"):printf("%d\n",ans);
    return 0;
}

D

思路:奇偶性剪枝??QAQ tql %%%%@hjf 真的太巨了 能减掉一堆无用的状态QAQ 所以不难得出几种剪枝QAQ{1 时间不够的提前减掉 2 奇偶性剪枝 3 在搜索前特判(eg: 3 3 4

              SXX

              .XX

              X.D

上面的例子满足m*n-wall=t,确实不能到达,但不能找到合理的解释......

)}

脑补一下 temp&1 == temp%2==1 QAQ

DFS 的参数//当前位置坐标(x,y),到目前位置消耗时间

#include <bits/stdc++.h>
#define f(i,j,n) for(register int i=j;i<=n;i++)
using namespace std;
typedef long long ll;
inline ll read() {
    ll x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch-48),ch=getchar();
    return x*f;
}
char a[10][10];
int n,m,t;
int sx,sy,ex,ey;
bool flag;
int dir[4][2]= {0,1,1,0,0,-1,-1,0};
int abs(int x) {
    return x<0?-x:x;
}
void DFS(int x,int y,int time) {
    if(x<0 or x>=n or y<0 or y>=m) return;
    if(x==ex and y==ey and time==t) {
        flag=true;
        return ;
    }
    if(flag) return;
    int temp=(t-time)-(abs(x-ex)+abs(y-ey));
    if(temp<0 or temp&1) return;
    f(i,0,3) {
        int xx=x+dir[i][0],yy=y+dir[i][1];
        if(a[xx][yy]!='X') {
            a[xx][yy]='X',DFS(xx,yy,time+1),a[xx][yy]='.';
            if(flag) return ;
        }
    }
}
int main() {
    while(1) {
        n=read(),m=read(),t=read();
        if(!n and !m and !t) return 0;
        int wall=0;
        f(i,0,n-1)
        f(j,0,m-1) {
            cin>>a[i][j];
            if(a[i][j]=='S') sx=i,sy=j;
            if(a[i][j]=='D') ex=i,ey=j;
            if(a[i][j]=='X') wall++;
        }
        if(n*m-wall<=t) {
            puts("NO");
            continue;
        }
        flag=false,a[sx][sy]='X';
        DFS(sx,sy,0);
        flag?puts("YES"):puts("NO");
    }
}

更新完毕QAQ...

猜你喜欢

转载自blog.csdn.net/qq_42628055/article/details/85221027
今日推荐