zoukankan      html  css  js  c++  java
  • 【BZOJ】1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(暴力dfs+set判重)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1675

    一开始我写了个枚举7个点。。。。。。。

    但是貌似。。。

    写挫了。

    然后我就写dfs。。

    判重好难写啊。

    。。。。

    本来用hash的。。

    但是对拍一直wa。。

    所以干脆用set。。

    然后将数值调大。。

    然后就过了。。

    然后bzoj数据弱。。

    自己对拍还是hash有冲突的。。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << #x << " = " << x << endl
    #define printarr(a, n, m) for1(aaa, 1, n) { for1(bbb, 1, m) cout << a[aaa][bbb]; cout << endl; }
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const int md=1000000007;
    int mp[7][7], vis[7][7], ans;
    set<int> hs;
    const int dx[]={-1, 1, 0, 0}, dy[]={0, 0, -1, 1};
    int Hash() {
    	int ret=0, k=7;
    	for1(i, 1, 5) for1(j, 1, 5) if(vis[i][j]) {
    		ret=(ret+(((mp[i][j]*k)%md)*(i*5+j)%md))%md;
    		k=(k*7)%md;
    	}
    	return ret;
    }
    bool check(int x, int y) {
    	rep(i, 4) if(vis[x+dx[i]][y+dy[i]]) return 1;
    	return 0;
    }
    void dfs(int now, int a, int b) {
    	if(now==8) {
    		if(a>b) {
    			int h=Hash();
    			if(hs.count(h)==0) { hs.insert(h); ++ans; }
    		}
    		return;
    	}
    	for1(i, 1, 5) for1(j, 1, 5) if(!vis[i][j] && (check(i, j) || now==1)) {
    		vis[i][j]=1;
    		dfs(now+1, a+(mp[i][j]==31), b+(mp[i][j]==43));
    		vis[i][j]=0;
    	}
    }
    
    int main() {
    	for1(i, 1, 5) for1(j, 1, 5) {
    		char ch; for(ch=getchar(); !(ch=='H'||ch=='J'); ch=getchar());
    		if(ch=='J') mp[i][j]=31;
    		else mp[i][j]=43;
    	}
    	dfs(1, 0, 0);
    	print(ans);
    	return 0;
    }
    

    后边写的枚举每个点

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << #x << " = " << x << endl
    #define printarr(a, n, m) for1(aaa, 1, n) { for1(bbb, 1, m) cout << a[aaa][bbb]; cout << endl; }
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    int mp[7][7], ans, xy[10], x[10], y[10], vis[7][7], vv[7][7], cnt;
    const int dx[]={-1, 1, 0, 0}, dy[]={0, 0, -1, 1};
    void dfs(int x, int y) {
    	vv[x][y]=1;
    	++cnt;
    	rep(i, 4) {
    		int fx=dx[i]+x, fy=dy[i]+y;
    		if(vis[fx][fy] && !vv[fx][fy]) dfs(fx, fy);
    	}
    }
    bool check() {
    	for1(i, 1, 7) x[i]=(xy[i]+4)/5, y[i]=xy[i]-(x[i]-1)*5;
    	CC(vis, 0); CC(vv, 0);
    	for1(i, 1, 7) vis[x[i]][y[i]]=1;
    	cnt=0;
    	dfs(x[1], y[1]);
    	if(cnt!=7) return 0;
    	int sum=0;
    	for1(i, 1, 7) sum+=mp[x[i]][y[i]];
    	return sum>3;
    }
    int main() {
    	for1(i, 1, 5) for1(j, 1, 5) {
    		char ch; for(ch=getchar(); ch!='H'&&ch!='J'; ch=getchar());
    		mp[i][j]=ch=='J';
    	}
    	for(xy[1]=1; xy[1]<=19; ++xy[1])
    		for(xy[2]=xy[1]+1; xy[2]<=20; ++xy[2])
    			for(xy[3]=xy[2]+1; xy[3]<=21; ++xy[3])
    				for(xy[4]=xy[3]+1; xy[4]<=22; ++xy[4])
    					for(xy[5]=xy[4]+1; xy[5]<=23; ++xy[5])
    						for(xy[6]=xy[5]+1; xy[6]<=24; ++xy[6])
    							for(xy[7]=xy[6]+1; xy[7]<=25; ++xy[7])
    								if(check()) ++ans;
    	print(ans);
    	return 0;
    }
    

    Description

    It's election time. The farm is partitioned into a 5x5 grid of cow locations, each of which holds either a Holstein ('H') or Jersey ('J') cow. The Jerseys want to create a voting district of 7 contiguous (vertically or horizontally) cow locations such that the Jerseys outnumber the Holsteins. How many ways can this be done for the supplied grid?

     农场被划分为5x5的格子,每个格子中都有一头奶牛,并且只有荷斯坦(标记为H)和杰尔西(标记为J)两个品种.如果一头奶牛在另一头上下左右四个格子中的任一格里,我们说它们相连.    奶牛要大选了.现在有一只杰尔西奶牛们想选择7头相连的奶牛,划成一个竞选区,使得其中它们品种的奶牛比荷斯坦的多.  要求你编写一个程序求出方案总数.

    Input

    * Lines 1..5: Each of the five lines contains five characters per line, each 'H' or 'J'. No spaces are present.

        5行,输入农场的情况.

    Output

    * Line 1: The number of distinct districts of 7 connected cows such that the Jerseys outnumber the Holsteins in the district.

        输出划区方案总数.

    Sample Input

    HHHHH
    JHJHJ
    HHHHH
    HJHHJ
    HHHHH

    Sample Output

    2

    HINT


    Source

  • 相关阅读:
    生成类似于MongoDB产生的ObjectId
    链式编程:遇到多个构造器参数(Constructor Parameters)时要考虑用构建器(Builder)
    mysql时间字符串按年/月/天/时分组查询 -- date_format
    根据模板导出excel
    九度 1188 约瑟夫环问题
    快速排序
    Linux 命令
    volatile小记
    线程池ThreadPoolExecutor
    CyclicBarrier、CountDownLatch与Semaphore的小记
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3970692.html
Copyright © 2011-2022 走看看