练习赛20150412

这套题分别在总结3313~3321

A.

B.大模拟,敲了好长时间。。。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char str[35][1000] = {
"111111MMM11111111MMMMMMMMMMM111111111MMMMMMMM1111MMMMMMMMMMM11111MMMMMMMMMMMM1111MMMMMMMMMMMMM11"
,"11111MM1MM1111111MM11111111MM111111MM1111111MM111MM111111111MM111MM11111111111111MM1111111111111"
,"1111MM111MM111111MM11111111MM11111MM111111111MM11MM1111111111MM11MM11111111111111MM1111111111111"
,"111MMMMMMMMM11111MMMMMMMMMMM111111MM1111111111111MM1111111111MM11MMMMMMMMMMMM1111MMMMMMMMMMMMM11"
,"11MM1111111MM1111MM11111111MM11111MM111111111MM11MM1111111111MM11MM11111111111111MM1111111111111"
,"1MMM11111111MM111MM11111111MM111111MM1111111MM111MM111111111MM111MM11111111111111MM1111111111111"
,"1MM1111111111MM11MMMMMMMMMMM111111111MMMMMMMM1111MMMMMMMMMMM11111MMMMMMMMMMMM1111MM1111111111111"
,"11111MMMMMMMM1111MM111111111MM1111111MMMMMM111111111MMMMMMMM111111MM111111MMM11111MM111111111111"
,"111MM1111111MM111MM111111111MM111111111MM11111111111111MM111111111MM11111MMM111111MM111111111111"
,"11MM111111111MM11MM111111111MM111111111MM11111111111111MM111111111MM111MMM11111111MM111111111111"
,"11MM1111111111111MMMMMMMMMMMMM111111111MM11111111111111MM111111111MMMMM11111111111MM111111111111"
,"11MM111111MMMMM11MM111111111MM111111111MM1111111111MM11MM111111111MM111MMM11111111MM111111111111"
,"111MM1111111MM111MM111111111MM111111111MM1111111111MMM1MM111111111MM11111MMM111111MM111111111111"
,"11111MMMMMMMMM111MM111111111MM1111111MMMMMM1111111111MMMM111111111MM111111MMMM1111MMMMMMMMMMMM11"
,"1MM1111111111MM11MMM111111111MM111111MMMMMM111111MMMMMMMMMMM111111111MMMMMM111111MMMMMMMMMMM1111"
,"1MMMM111111MMMM11MMMM11111111MM1111MMM1111MMM1111MM111111111MM11111MMM1111MMM1111MM111111111MM11"
,"1MM1MM1111MM1MM11MM1MM1111111MM111MMM111111MMM111MM1111111111MM111MMM111111MMM111MM1111111111MM1"
,"1MM11MMMMM111MM11MM11MM111111MM11MM1111111111MM11MM111111111MM111MM1111111111MM11MM111111111MM11"
,"1MM1111M11111MM11MM1111MM1111MM111MMM111111MMM111MMMMMMMMMMM111111MMM1MMMM1MMM111MMMMMMMMMMM1111"
,"1MM1111111111MM11MM111111MMM1MM1111MMM1111MMM1111MM1111111111111111MMM11MMMMM1111MM11111111MM111"
,"1MM1111111111MM11MM11111111MMMM111111MMMMMM111111MM1111111111111111111MMMM1MMMM11MM111111111MMM1"
,"1111MMMMMMMM111111MMMMMMMMMMMM111MM1111111111MM11MMMM111111MMMM11MM1111111111MM111MMM111111MMM11"
,"111MM1111111MM1111MMMMMMMMMMMM111MM1111111111MM111MMM111111MMM111MM1111111111MM1111MMM1111MMM111"
,"11MMM1111111MMM11111111MM11111111MM1111111111MM111MMM111111MMM1111MM111MM111MM111111MMM11MMM1111"
,"1111MMMMM11111111111111MM11111111MM1111111111MM1111MMM1111MMM11111MM111MM111MM11111111MMMM111111"
,"1MMM111MMMM111111111111MM11111111MMM11111111MMM11111MMM11MMM111111MM111MM111MM111111MMM11MMM1111"
,"111MMM11111MMM111111111MM11111111MMM11111111MMM111111MM11MM1111111MM1MM11MM1MM11111MMM1111MMM111"
,"11111MMMMMMM11111111111MM1111111111MMMMMMMMMM111111111MMMM111111111MMM1111MMM11111MMM111111MMM11"
,"11MMM111111MMM11111MMMMMMMMMM111"
,"111MMM1111MMM1111111111111MM1111"
,"1111MMM11MMM1111111111111MM11111"
,"111111MMMM11111111111111MM111111"
,"1111111MM1111111111111MM11111111"
,"1111111MM111111111111MM111111111"
,"1111111MM1111111111MMMMMMMMMMM11"
};
int num[30];            //强联通有多少个节点
int weizhi[26][7*16][2];        //第i个字母dfs到的地k各节点与起点的差
int nn;
int judge(int x, int y, int x1, int x2, int y1, int y2){
    if(x1 <= x && x <= x2 && y1 <= y && y <= y2 && str[x][y] =='M')return 1;
    return 0;
}
int move[8][2] = {0, 1, 0, -1, 1, 0, 1, -1, 1, 1, -1, 0, -1, -1, -1, 1};
int vis[305][305], vis1[305][305];
int dfs(int x, int y, int sx, int sy, int x1, int x2, int y1, int y2){//printf("%d %d %d %d %d %d %d %d\n", x, y, sx, sy,x1,x2,y1,y2);

    if(vis[x][y])return 0;
    vis[x][y] = 1;
    weizhi[nn][num[nn]][0] = sx-x;
    weizhi[nn][num[nn]++][1] = sy-y;
    /*if(nn == 'u'-'a'){
       printf("**%d %d %d %d\n", weizhi['u'-'a'][num[nn]-1][0], weizhi['u'-'a'][num[nn]-1][1], sx-x, sy-y);
    }*/
    for(int i  = 0; i < 8; i++){
        if(judge(x+move[i][0], y+move[i][1],x1,x2, y1, y2)){//printf("**%d %d %d %d %d %d %d %d\n", x+move[i][0], y+move[i][1], sx, sy,x1,x2,y1,y2);
            dfs(x+move[i][0], y+move[i][1], sx, sy,x1,x2, y1, y2);
        }
    }
}
char str1[305][305];
int judge1(int x, int y, int n, int m){
    if(0 <= x && x < n && 0 <= y && y < m && str1[x][y] == 'M')
        return 1;
    return 0;
}
int nnu, dp;
void dfs1(int x, int y, int n, int m, int sx, int sy){//printf("%d %d %d %d\n", x, y, sx, sy);

    if(vis1[x][y])return;
    vis1[x][y] = 1;
    if(nnu < 7*17){
        //printf("**%d %d ", weizhi['u'-'a'][nnu][0], weizhi['u'-'a'][nnu][1]);
        //printf("%d ", dp);
        int s= 0;
        int xx = sx - x, yy = sy - y;
        for(int i = 0; i < 26; i++){
            if(weizhi[i][nnu][0] == xx && weizhi[i][nnu][1] == yy){
                s |= (1<<i);
            }
        }//printf("--%d--", s);
        dp &= s;
        //printf("%d %d %d %d\n", sx-x,sy-y, dp, s);
        nnu++;
    }else dp = 0;
    for(int i  = 0; i < 8; i++){
        if(judge1(x+move[i][0], y+move[i][1], n, m)){
            dfs1(x+move[i][0], y+move[i][1], n, m, sx, sy);
        }
    }
}
int ans[30];
int Ans(int n, int m){
    memset(vis1, 0, sizeof(vis1));;
    for(int i = 0; i < n; i++){
        for(int k = 0; k < m; k++){
            if(vis1[i][k] || str1[i][k]!='M')continue;
            nnu = 0;
            dp = (1<<26)-1;
            dfs1(i, k, n, m, i, k);//printf("**%d\n", dp);
            for(int j = 0; j < 26; j++){
                if(((1<<j) & dp) && nnu == num[j]){
                    ans[j] = 1;
                }
            }
        }
    }
}
char ss[305][305];
int main(){
    for(int i =0; i < 35; i+= 7){
        for(int k = 0; k < 96; k+=16){
            int x1 = i,x2 = i+6, y1 = k, y2 = k+16;
            for(int ii = i; ii < i+7; ii++){
                for(int kk = k; kk < k +16; kk++){
                    if(vis[ii][kk])continue;
                    if(str[ii][kk] == 'M'){//printf("%d %d\n", ii, kk);
                        dfs( ii, kk, ii, kk,x1,x2,y1,y2);
                    }
                }
            }
            nn++;
            if(nn == 26)break;
        }
    }
    int n, m;
    while(scanf("%d%d", &n, &m)!=EOF){
        memset(ans, 0, sizeof(ans));
        for(int i = 0;i < n; i++){
            scanf("%s", str1[i]);
        }
        //Ans(n, m);
        for(int u = 0; u < 4; u++){
            Ans(n, m);
            for(int i = 0;i  < m; i++){
                for(int k = 0; k < n ;k++){
                    ss[i][k] = str1[n-1-k][i];
                }
            }swap(n, m);
            for(int i =0 ; i <n;i++){
                for(int k = 0; k < m ; k++){
                    str1[i][k] = ss[i][k];
                }
            }
        }
        for(int i = 0;i  < 26; i++){
            if(ans[i])printf("%c", 'A'+i);
        }puts("");
    }
}
View Code

C.

D.

E.简单模拟题,又wa了好多次,当时脑子坏掉

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxa = 105;
struct point{
    int in, out, id;
}p[maxa];
int cmp(point a, point b){
    return a.in < b.in;
}
int room[maxa], liveroom[maxa];;
int ans[maxa];
int main(){
    int n, m;
    while(scanf("%d%d", &n, &m)!=EOF){
        if(n == 0 && m == 0)return 0;
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &p[i].in, &p[i].out);
            p[i].id = i;
        }
        sort(p+1, p+n+1, cmp);
        memset(room, 0, sizeof(room));
        memset(liveroom, 0, sizeof(liveroom));
        memset(ans, 0, sizeof(ans));
        for(int i = 1;i <= n; i++){
            for(int k = 1; k <= m; k++){
                if(liveroom[k] <= p[i].in){
                    liveroom[k] = p[i].out;
                    ans[p[i].id] = k;
                    liveroom[k] = p[i].out;
                    break;
                }
            }
        }
        for(int i =1 ; i<= n; i++){
            printf("%d\n", ans[i]);
        }
    }
}
View Code

F.有m张地图,有一个起点s和一个终点t,一条路径的价值是s到t的距离+与上一路径相同?0:1.

由于只有三十条路径所以可以将所有图压缩到一个图上,点也不多,dp[i] = dp[j]+bfs(j+1,i),bfs(j+1,i)指的是j+1到i路径相同所产生的值,广搜可以做到。

ps:(可能如果有更多的时间能想到,但是当时状态不好加敲打模拟用去大量时间。。。。。)

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int maxa  = 35;
int edge[maxa][maxa];
int n, m, s, t;
int vis[maxa];
int dp[maxa];
int bfs(int ii, int kk){
    memset(vis, -1, sizeof(vis));
    vis[s] = 0;
    queue<int> Q;
    Q.push(s);//puts("");
    while(!Q.empty()){
        int now = Q.front(); Q.pop();//printf("**%d\n", now);
        if(now == t) break;
        for(int i = 0 ; i < n; i++){
            int ok = 1;
            if(vis[i] != -1)continue;
            for(int k = ii; k <= kk; k++){
                //printf("%d %d %d\n", edge[now][i], now, i);
                if((edge[now][i] & (1<<k)) == 0){
                    ok =0;
                    break;
                }
            }
            if(ok){
                vis[i] = vis[now]+1;
                Q.push(i);
            }
        }
    }//printf("--%d %d %d\n",ii, kk, vis[t]);
    if(vis[t] == -1)return 100000;
    if(ii == 0)return (kk-ii+1)*vis[t];
    return (kk-ii+1)*vis[t]+1;
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d%d%d", &n, &m, &s, &t);
        s--,t--;
        memset(edge, 0, sizeof(edge));
        for(int i = 0; i < m; i++){
            int r;
            scanf("%d", &r);
            while(r--){
                int x, y;
                scanf("%d%d", &x, &y);x--,y--;
                edge[x][y] |= (1<<i);
                edge[y][x] |= (1<<i);
            }
        }//bfs(0, 0);
        for(int i =0 ;i < m; i++)dp[i] = 1000000;
        for(int i = 0;i < m; i++){
            for(int k = 0;k <= i; k++){
                if(k == 0){
                    dp[i] = min(dp[i],bfs(k, i));
                }else{
                    dp[i] = min(dp[i], dp[k-1]+bfs(k, i));
                }
            }
        }
        /*for(int i = 0;i < m; i++){
            printf("*%d\n", dp[i]);
        }*/
        printf("%d\n", dp[m-1]);
    }
}
View Code

G.错排公式,错排公式是让n个点每个点都不在原来的位置,有多少中排列情况。d[i] = (n-1)*(d[i-1]+d[i-2]),很常用的一个公式,然后只要枚举有多少个链形成自环其他错排,有种情况就是有自环或者有环但是有零个点错排,这样加一。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxa = 105;
int rudu[maxa], chudu[maxa];
char str[maxa][maxa];
int dp[maxa];
const int mod = 10000007;
long long c[maxa][maxa];
void table()
{
   int i,j;
   for(i=0;i<maxa;i++)
   {
       for(j=0;j<=i;j++)
       {
           if(!j||i==j)
            c[i][j]=1;
           else
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
       }
   }
   return;
}
int next[maxa];
int main(){
    table();
    dp[2] = 1;
    for(int i = 3; i < maxa; i++){
        dp[i] = (i-1)*(dp[i-1]+dp[i-2]);
        dp[i] %= mod;
    }
    dp[0] = 0;
    int n;
    while(scanf("%d", &n), n){
        for(int i = 0; i < n; i++){
            next[i] = -1;
        }
        memset(rudu, 0, sizeof(rudu));
        memset(chudu, 0, sizeof(chudu));
        for(int i =0;i  < n; i++){
            scanf("%s", &str[i]);
        }
        for(int i = 0;i <  n; i++){
            for(int k =0;k < n; k++){
                if(str[i][k] == 'Y'){
                    rudu[i] ++;
                    chudu[k] ++;
                    next[i] = k;
                }
            }
        }
        int ok = 1;
        int nn = 0;
        int mm = 0;
        for(int i =0;i < n; i++){
            if(rudu[i] > 1 || chudu[i] > 1){
                ok =0;
            }
            if(rudu[i] == 0){
                nn ++;
                if(chudu[i] != 0)mm++;
            }
        }
        if(ok == 0){
            printf("0\n");
        }else{
            int huan = 0;
            for(int i =0 ;i < n; i++){
                int ii = next[i];
                while(ii != -1){
                    if(ii == i){
                        huan = 1;
                        break;
                    }
                    ii = next[ii];
                }
            }
            int ans = 0;
            for(int i = 0; i <= mm; i++){
                if((huan || i > 0)&&(nn-i)==0){//printf("*");
                    ans ++;
                }
                ans += int((c[mm][i]*dp[nn-i])%mod);
                ans %= mod;
            }
            printf("%d\n", ans);
        }
    }
}
/*
5
NYNNN
NNNNN
NNNYN
YNNNN
NNNNN
*/
View Code

 

posted @ 2015-04-14 15:48  icodefive  阅读(564)  评论(0编辑  收藏  举报