sgu224Little Queens 225. Little Knights

版权声明:转我原创记得说你是我的脑残粉哟 https://blog.csdn.net/zjy2015302395/article/details/77568827

题意:

n*n(n<=10)的棋盘,求出放置m(m<=n*n)个皇后的方案数。

tip:

状态压缩+位运算 一行一行dfs
dfs(当前行号,列状态(哪个可以选可以不选),左上来的(哪个可以选可以不选),右上来的(哪个可以选可以不选),已放置棋子数)

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

int n,sum,bound,m;
void dfs(int step , int cal, int l, int r, int num) {
    int pos, p, i;
    if (step > n){
        if(num == m) sum++;
        return;
    }
    dfs(step + 1, cal, l>>1, r<<1, num);
    if (cal != bound){
        pos = (bound & (~ (cal|l|r)));
        while (pos != 0){
            p = pos & -pos;//last "one"
            pos = pos - p;
            dfs (step+1,cal|p,(l|p)>>1,(r|p)<<1,num+1);
        }
    }
}
int main() {
//  int p =8&-8;
//  cout <<p<<endl;
    scanf("%d%d",&n,&m);
    bound = (1<<n) - 1;
    dfs(1,0,0,0,0);
    printf("%d",sum);
}

题意:

放马

tip:

还是状压,位运算。。要打表

#include <cstdio>
#include <cstring>
#include <iostream>
#define LL long long
using namespace std;
LL  mark[110]={1,100,4662,135040,2732909,41199404,481719518,4491423916,34075586550,213628255072,1120204619108,4961681221524,18715619717199,60541371615660,168976761361446,409191804533576,864172675710439,1599730843649564,2609262108838924,3770687313420780,4857550050070531,5616928666465104,5874943705896600,5604501518609804,4917655076255841,3999855946779732,3034690618677388,2156485957257040,1437827591264317,899278231344296,526753407546620,288274613750624,146990556682887,69626509814580,30542906352994,12366448408056,4604442057431,1569983914256,487876545370,137395261280,34831261750,7884855000,1578162590,275861904,41455966,5246412,543534,44244,2652,104,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int state[30000];
int fstate[(1<<20)+1000];
int statenum =0 ;
LL f[2][29000][52];
int n,k;
int bitnum(int x){
    int sum =0;
    while(x){
      int  t = x&(-x);
      sum++;
      x -= t;
    }
    return sum;
}
void init_state(){
    statenum =0;
    int line1 ;
    int line2 ;
    for(int i = 0 ;i < (1<<(2*n) ) ;i++){
        line2 = i>>n;
        line1 = i- (line2 << n);
        if(line2&(line1<<2))    continue;
        if(line2&(line1>>2))    continue;
        statenum ++;
        state[statenum]= i;
        fstate[i] =statenum;
  }
}
int maxidx[20]={0,1,5,6,9,14,18,26,32,42,51};
void dfs(int r , int  i,int j, int  lev,int num){
      int line1 = ( j>>n );
      int line2 =  (line1<<n);
          line2 = j - line2;
      if(lev == n){
        for(int t = num;t <= maxidx[n];t++){
            int tmp = (line2<<n)+i;
            f[r%2][fstate[tmp]][t] += f[(r+1)%2][fstate[j]][t-num];
        }
        return ;
     }
     int st = (line1>>1)|(line1<<1)|(line2>>2)|(line2<<2);

     dfs(r,i,j,lev+1,num);
     if((st&(1<<lev)) == 0){
          dfs(r,i|(1<<lev),j,lev+1,num+1);
     }
}

void sov(){
    if(n == 10){
        cout << mark[k]<<endl;
        return ;
    }
    if(k > maxidx[n]){
        cout << 0 <<endl;;
        return ;
    }
    init_state();
    memset(f,0,sizeof(f));
    for(int  i = 1;i <= min(statenum,(1<<n)); i++){
        f[1][i][bitnum(state[i])]=1;
    }
    f[1][1][0]=1;
    for(int r=1;r<n;r++){
        memset(f[(r+1)%2],0,sizeof(f[(r+1)%2]));
        for(int j = 1;j <= statenum;j++){
            dfs(r+1,0,state[j],0,0);
        }
    }
    LL ans =  0;
    for(int i = 1;i <= statenum;i++){
        ans +=  f[n%2][i][k];
    }
    cout <<ans<<endl;;
}

int main(){
    cin >> n>>k;
    sov();
    return 0 ;
}
阅读更多

Knights

08-02

Problem DescriptionnAt the start of this game, there are N knights on a road of length N+1. The knights are numbered from 1 to N, and the ith knight stands i unit from the left end of the road.nnWhen the game begins, each knight moves to left or right at the same speed. Whenever a knight reaches to the end of the road, he instantly changes his direction. nnWhenever two knights meet, they fight until one loses, where each one of them wins in 50% possibility. Then the winner keeps moving in the direction he was moving before the fight, and the loser quits the game. The fighting time is very short and can be ignored.nnThe game continues until only one knight remains, and that knight is the winner.nnNow, we know the moving direction of each knight initially. Can you calculate the possibility that Nth knight win the game?n nnInputnThe first line of the input gives the number of test cases T (T <= 10). In each test case, the first line is an integer N (1 <= N <= 1000). The second line contains N integers. The ith integer represents the ith knight’s moving direction, and 0 stands for left while 1 stands for right.n nnOutputnEach test case contains one line and one integer. Let’s assume the possibility be equal to the irreducible fraction P / Q. Print the value of P⋅Q−1 in the prime field of integers modulo 1 000 000 007(109+7). It is guaranteed that this modulo does not divide Q, thus the number to be printed is well-defined.n nnSample Inputn2n2n0 0n3n0 1 0n nnSample OutputnCase #1: 500000004nCase #2: 250000002

没有更多推荐了,返回首页