zoukankan      html  css  js  c++  java
  • 17国庆day2

    2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) 

     题解:链接

    Tournament Wins

     Gym - 101201K 

    题意: 2^k个人,你排名第r, 问你能赢的期望次数.

    至少赢 i 次的概率是 C(2^i-1, 2^k-r) / C(2^i-1, 2^k-1) ,化简一下

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int k, r;
     4 
     5 int main() {
     6         scanf("%d %d", &k, &r);
     7         int m = (1<<k) - r;
     8         double ans = 0;
     9         int i;
    10         for(i = 1; (1<<i)-1 <= m; i++){
    11             double p = 1.0;
    12            // int a = (1<<k) - (1<<i) + 2 - r;
    13             //int c = (1<<k) - r + 1;
    14             int a = (1<<k) - 1;
    15             int c = (1<<k) - r;
    16             for(int j = 0; j <(1<<i)-1 ; j++) {
    17                 p = p*c/a;
    18                 a--;
    19                 c--;
    20             }
    21             ans += p;
    22         }
    23         printf("%.5lf
    ", ans);
    24 }
    View Code

    Maximum Islands

     Gym - 101201G 

    题意: 给一个卫星图, 有陆地, 海洋和未知区域, 问最多有多少个陆地四连块.

    首先明确已知的陆地周围必须都是海洋, 然后未知区域单独为陆地的情况下四连块才会最多.

    黑白染色,求二分图最大独立集.

    又是二分图匹配....感觉自己好菜哇=_=

     1 #include <bits/stdc++.h>
     2 #define CLR(m, a) memset(m, a, sizeof(m))
     3 using namespace std;
     4 const int maxn = 1610;
     5 
     6 struct Edge{
     7     int v, nex;
     8     Edge(int v=0, int nex=0) : v(v), nex(nex) {}
     9 }e[maxn<<2];
    10 int head[maxn];
    11 int cnt;
    12 
    13 void init(){
    14     CLR(head,-1);
    15     cnt = 0;
    16 }
    17 void add(int u, int v) {
    18     e[cnt] = Edge(v, head[u]) ;
    19     head[u] = cnt++ ;
    20 }
    21 
    22 char p[42][42];
    23 int vis[42][42];
    24 
    25 int n, m;
    26 int dir[4][2] = {0,1,0,-1,1,0,-1,0};
    27 void dfs(int x, int y){
    28     vis[x][y] = 1;
    29     for(int i = 0; i < 4; i++){
    30         int dx = x + dir[i][0];
    31         int dy = y + dir[i][1];
    32         if(dx>=0&&dx<n&&dy>=0&&dy<m&&!vis[dx][dy]) {
    33             if(p[dx][dy] == 'L') dfs(dx,dy);
    34             if(p[dx][dy] == 'C') p[dx][dy] = 'W';
    35         }
    36     }
    37 }
    38 
    39 int vb[maxn], vg[maxn], mcb[maxn];
    40 
    41 int Hungary(int u){
    42     vg[u] = 1;
    43     for(int i = head[u]; ~i; i = e[i].nex){
    44         int v = e[i].v;
    45         if(!vb[v]){
    46             vb[v] = 1;
    47             if(mcb[v] == -1 || Hungary(mcb[v])) {
    48                 mcb[v] = u;
    49                 return 1; 
    50             }
    51         }
    52     }
    53     return 0;
    54 }
    55 
    56 int main(){
    57   //  freopen("in.txt", "r", stdin);
    58     while(scanf("%d %d", &n, &m)!= EOF) {
    59         init();
    60         for(int i = 0; i < n; i++) scanf("%s", p[i]);
    61         int tot = 0;
    62         CLR(vis, 0);
    63         for(int i = 0; i < n; i++){
    64             for(int j = 0; j < m; j++){
    65                 if(p[i][j] == 'L'&& !vis[i][j]) {
    66                     dfs(i,j);
    67                     tot++;
    68                 }
    69             }
    70         }
    71         CLR(vis, 0);
    72         int N = 0;
    73         for(int i = 0; i < n; i++) 
    74             for(int  j = 0; j < m; j++) 
    75                 if(p[i][j]=='C') vis[i][j] = ++N;
    76 
    77         for(int i = 0; i < n; i++) {
    78             for(int j = 0; j < m; j++) {
    79                 if((i+j)%2==0 && vis[i][j]) {
    80                     for(int k = 0; k < 4; k++) {
    81                         int dx = i+dir[k][0];
    82                         int dy = j+dir[k][1];
    83                         if(dx>=0 && dx<n && dy>=0 && dy<m && vis[dx][dy]) add(vis[i][j], vis[dx][dy]); 
    84                     }
    85                 }
    86             }
    87         }
    88         int ans = 0;
    89         CLR(mcb, -1);
    90         for(int i = 0; i < n; i++)
    91             for(int j  = 0; j < m; j++)
    92                 if(vis[i][j] && (i+j)%2 == 0) {
    93                     CLR(vg, 0);
    94                     CLR(vb, 0);
    95                     if(Hungary(vis[i][j])) ans++;
    96                 }
    97         printf("%d
    ", N - ans + tot);
    98     }
    99 }
    View Code

    Alphabet

     Gym - 101201A 

    求最长上升子序列.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 55;
     4 char s[maxn];
     5 int d[maxn];
     6 int main() {
     7     //freopen("in.txt", "r", stdin);
     8     while(scanf("%s", s) != EOF) {
     9         int n = strlen(s);
    10         int ans = 0;
    11         memset(d, 0, sizeof(d));
    12         for(int i = 0; i < n; i++) {
    13             for(int j = 0; j < i; j++) {
    14                 if(s[j] < s[i]) d[i] = max(d[i], d[j]+1);
    15                 ans = max(ans, d[i]);
    16             }
    17         }
    18         printf("%d
    ", 25 - ans);
    19     }
    20 }
    View Code

    Cameras

     Gym - 101201C 

    暴力也能过,有点慢900+ms

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 100010;
     5 
     6 int vis[maxn];
     7 int n, k, r;
     8 
     9 int main(){
    10  //   freopen("in.txt", "r", stdin);
    11     while(scanf("%d %d %d", &n, &k, &r) != EOF) {
    12         memset(vis, 0, sizeof(vis));
    13         for(int i = 0; i < k; i++) {
    14             int x;
    15             scanf("%d", &x);
    16             vis[x] = 1;
    17         }
    18         int res = 0;
    19         for(int i = 1; i+r-1 <= n; i++) {
    20             int cnt = 0;
    21             for(int j = i; j <= r+i-1; j++){
    22                 if(vis[j]) cnt++;
    23                 if(cnt==2) break;
    24             }
    25             int id = r+i-1;
    26             while(cnt<2) {
    27                 while(vis[id]) id--;
    28                 vis[id] = 1;
    29                 cnt++;
    30                 res++;
    31              //   printf("---%d
    ", id);
    32             }
    33         }
    34         printf("%d
    ", res);
    35     }
    36 }
    View Code

    其实可以用树状数组维护下区间和~ 30ms

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 100010;
     5 
     6 int c[maxn], vis[maxn];
     7 int n, k, r;
     8 
     9 int lowbit(int x) {
    10     return x&(-x);
    11 }
    12 void add(int x, int d){
    13     while(x <= n) {
    14         c[x] += d;
    15         x += lowbit(x);
    16     }
    17 }
    18 
    19 int sum(int x) {
    20     int ans = 0;
    21     while(x > 0) {
    22         ans += c[x];
    23         x -= lowbit(x);
    24     }
    25     return ans;
    26 }
    27 
    28 int main(){
    29     //freopen("in.txt", "r", stdin);
    30     while(scanf("%d %d %d", &n, &k, &r) != EOF) {
    31         memset(c, 0, sizeof(c));
    32         memset(vis, 0, sizeof(vis));
    33         for(int i = 0; i < k; i++) {
    34             int x;
    35             scanf("%d", &x);
    36             vis[x] = 1;
    37             add(x, 1);
    38         }
    39         int res = 0;
    40         for(int i = 1; i+r-1 <= n; i++) {
    41             int cnt = sum(r+i-1) - sum(i-1);
    42             int id = r+i-1;
    43             while(cnt<2) {
    44                 while(vis[id]) id--;
    45                 add(id, 1);
    46                 vis[id] = 1;
    47                 cnt++;
    48                 res++;
    49             }
    50         }
    51         printf("%d
    ", res);
    52     }
    53 }
    View Code

    Shopping

     Gym - 101201J 

     题意:n件商品,k个人,每个人m元钱,从L走到R,每遇到一件商品就尽可能的多买,问最后剩余多少钱~

    二分查找当前区间内小于m的最前位置

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long 
     4 
     5 const int maxn = 200010;
     6 
     7 ll a[maxn];
     8 ll dp[maxn][30];
     9 
    10 void rmq_init(int n) {
    11     for(int i = 1; i <= n; i++) dp[i][0] = a[i];
    12     int k = 0;
    13     while(1<<(k+1) <= n+1) k++;
    14     for(int i = 1; i <= k; i++) {
    15         for(int j = 0; j + (1<<i) -1 <= n; j++) {
    16             dp[j][i] = min(dp[j][i-1], dp[j+(1<<i-1)][i-1]);
    17         }
    18     }
    19 }
    20 
    21 ll rmq(int L, int R) {
    22     int k = 0;
    23     while(1<<(k+1) <= R-L+1) k++;
    24     return min(dp[L][k], dp[R-(1<<k)+1][k]);
    25 }
    26 
    27 int main(){
    28     int n, k;
    29     //freopen("in.txt", "r", stdin);
    30     scanf("%d %d", &n, &k) ;
    31         for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    32         rmq_init(n);
    33         while(k--) {
    34             ll m;
    35             int p, q;
    36             scanf("%lld %d %d", &m, &p, &q);
    37             while(1){
    38                 int L = p, R = q;
    39                 while(L <= R) {
    40                     int M = (L + R) >> 1;
    41                     if(rmq(L,M) <= m) R = M-1;
    42                     else L = M+1;
    43               //      cout<<L<<"   "<<R<<endl;
    44                 }
    45                 if(L > q) {
    46                     printf("%lld
    ", m);
    47                     break;
    48                 }
    49             //  printf("%d %lld---
    ", L, a[L]);
    50                 p = L+1;
    51                 m %= a[L];
    52                 if(m==0) {
    53                     printf("%lld
    ", m);
    54                     break;
    55                 }
    56             }
    57         }
    58     
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    [ffmpeg 扩展第三方库编译系列] 关于 mingw32 下编译libcaca
    新版本的tlplayer for android ,TigerLeapMC for windows发布了
    tlplayer 所有平台版本支持水印叠加
    更新Windows ActiveX,Ios
    Linux批量“解压”JAR文件
    Linux进阶路线
    30个实用的Linux find命令示例
    Redhat 无线(Wifi)上网命令行配置
    PLSQL developer常用技巧
    Hibernate4.3.5搭建Log4j日志环境
  • 原文地址:https://www.cnblogs.com/yijiull/p/7624266.html
Copyright © 2011-2022 走看看