zoukankan      html  css  js  c++  java
  • SnackDown Online Pre-elimination round A

    1. 应该n是偶数,就行吧。应该判断1个人,只能出现一次吧。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 1e3 + 10;
     7  
     8 void yes() {cout << "yes" << endl;}
     9 void no() {cout << "no" << endl; }
    10 int n, c;
    11 int a[110];
    12 void solve() {
    13     memset(a, 0, sizeof a);
    14     cin >> n >> c;
    15     int x, y;
    16     bool tag = 0;
    17     for (int i = 0; i < c; i++) {
    18         cin >> x >> y;
    19         if(a[x] || a[y]) tag = 1;
    20         a[x] = a[y] = 1;
    21     }
    22     if(n % 2 == 1 || tag) no();
    23     else yes();
    24 }
    25  
    26 int main() {
    27    // freopen("test.in", "r", stdin);
    28     //freopen("test.out", "w", stdout);
    29     ios::sync_with_stdio(0);
    30     cin.tie(0); cout.tie(0);
    31     int _;
    32     cin >> _;
    33     while(_--)
    34     solve();
    35     return 0;
    36 }
    View Code

    2. 是否是一条蛇,这个浪费了一些时间。

    首先#必须组成1个连通分量,多于1个的,肯定是不行的。然后还有其他情况。判断连通分量, dfs或者bfs扫就行。

    1个连通分量怎么是一条蛇,我刚开始以为是dfs扫一遍,每一个点的只能有一个前驱和后继,但是这样枚举的复杂度很高,应该会tle。

    考虑到只有2行,然后总左到右进行考虑, 每次先考虑上下, 再考虑向右走,然后check,长度是否是#的个数。注意,最左边的点,可能第一个是第一行往下走,或者是第二行往上走,都是可以的。

    写的有点丑。

      1 #include<bits/stdc++.h>
      2 #define pb push_back
      3 typedef long long ll;
      4 using namespace std;
      5 typedef pair<int, int> pii;
      6 const int maxn = 1e3 + 10;
      7 int n;
      8 string s[2];
      9 int c;
     10 int cnt;
     11 bool vis[2][510];
     12 int dx[] = {0, 0, 1, -1};
     13 int dy[] = {1, -1, 0, 0};
     14 bool check(int x, int y) {
     15     if(x >= 0 && x < 2 && y >= 0 && y < n) return 1;
     16     return 0;
     17 }
     18 void dfs(int x, int y) {
     19     if(vis[x][y] || s[x][y] == '.') return;
     20     vis[x][y] = 1;
     21     cnt++;
     22     for (int i = 0; i < 4; i++) {
     23         int cx = x + dx[i], cy = y + dy[i];
     24         if(check(cx, cy)) {
     25             dfs(cx, cy);
     26         }
     27     }
     28 }
     29 void yes() {cout << "yes" << endl; }
     30 void no() {cout << "no" << endl; }
     31 void solve() {
     32     cin >> n;
     33     cin >> s[0] >> s[1];
     34     //cout << s[0] << " " << s[1] << endl;
     35     c = 0;
     36     for (int i = 0; i < n; i++) {
     37         if(s[0][i] == '#') c++;
     38         if(s[1][i] == '#') c++;
     39     }
     40     int x, y;
     41     x = y = -1;
     42     for (int j = 0; j < n; j++) {
     43         for (int i = 0; i < 2; i++) {
     44             if(s[i][j] == '#') {
     45                 x = i; y = j;
     46                 break;
     47             }
     48         }
     49         if(x != -1) break;
     50     }
     51     cnt = 0;
     52     memset(vis, 0, sizeof vis);
     53     dfs(x, y);
     54     //cout << x << " " << y << endl;
     55     //cout << c << " " << cnt << endl;
     56     if(cnt != c) {
     57         no(); return;
     58     }
     59     memset(vis, 0, sizeof vis);
     60     int dx = x, dy = y;
     61     //cout << x << " " << y << endl;
     62     while(cnt > 0) {
     63         vis[x][y] = 1;
     64         cnt--;
     65         if(cnt == 0) break;
     66         if(s[1 - x][y] == '#' && !vis[1 - x][y]) {
     67             x = 1 - x;
     68         } else if(y + 1 < n && s[x][y + 1] == '#') {
     69             y = y + 1;
     70         } else {
     71             break;
     72  
     73         }
     74     }
     75     if(cnt == 0) {
     76         yes(); return;
     77     }
     78     cnt = c;
     79     //cout << x << " d " << y << endl;
     80     x = 1 - dx, y = dy;
     81  
     82     if(s[x][y] != '#') {
     83         no(); return;
     84     }
     85     memset(vis, 0, sizeof vis);
     86     while(cnt > 0) {
     87         vis[x][y] = 1;
     88         cnt--;
     89         if(cnt == 0) break;
     90         if(s[1 - x][y] == '#' && !vis[1 - x][y]) {
     91             x = 1 - x;
     92         } else if(y + 1 < n && s[x][y + 1] == '#') {
     93             y = y + 1;
     94         } else {
     95             no();
     96             return;
     97  
     98         }
     99     }
    100     yes();
    101 }
    102  
    103 int main() {
    104    // freopen("test.in", "r", stdin);
    105     //freopen("test.out", "w", stdout);
    106     //ios::sync_with_stdio(0);
    107     //cin.tie(0); cout.tie(0);
    108     int _; cin >> _;
    109     while(_--)
    110     solve();
    111     return 0;
    112 }
    View Code

    3. 这个题目跟资格赛的题目有点像,但是比较难。考虑每个位置的上限是多少,多于这个数,肯定是要必须操作的。

    是这样的形式, 1, 2,3 。。。3,2,1, 首先经过这样的缩减。找到必须的操作。 同时又可以观察到,如果第二个数为1, 然后第三个位置的上限就变为2了,而不是3. 这点也很容易想到。每个点只影响左右的点,然后左右的

    点,再把这个值传递出去。最后的结果肯定是,没相邻的2个点,最多相差1,而且每个位置的值,都是这个位置可以到达的上限。然后操作,就很简单了,枚举每一个点作为中心, 用所有和减去这个数, 求的最小的需要操作次数,

    最后,别忘了加上必须的操作次数。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 1e5 + 10;
     7  
     8 int n;
     9 int a[maxn];
    10 void solve() {
    11     scanf("%d", &n);
    12     ll s = 0;
    13     for (int i = 1; i <= n; i++) {
    14         scanf("%d", &a[i]);
    15     }
    16     for (int i = 1; i <= n / 2; i++) {
    17         //cout << i << " " << a[i] << endl;
    18         //cout << n + 1 - i << " " << a[n + 1 - i] << endl;
    19         if(a[i] > i) {
    20             s += a[i] - i;
    21             a[i] = i;
    22         }
    23         if(a[n + 1 - i] > i) {
    24             s += a[n + 1 - i] - i;
    25             a[n + 1 - i] = i;
    26         }
    27     }
    28     n++;
    29     if(n % 2 == 0) {
    30         if(a[n / 2] > n / 2) {
    31             s += a[n / 2] - n / 2;
    32             a[n / 2] = n / 2;
    33         }
    34     }
    35     n--;
    36     //for (int i = 1; i <= n; i++)
    37         //cout << i  << " ad " << a[i] << endl;
    38     set<pii> se;
    39     for (int i = 1; i <= n; i++) {
    40         se.insert({a[i], i });
    41     }
    42     int x, y;
    43     while(!se.empty()) {
    44         pii t = *se.begin();
    45         se.erase(se.begin());
    46         y = t.first; x = t.second;
    47         if(x - 1 > 0) {
    48             if(a[x - 1] > y + 1) {
    49                 se.erase({a[x - 1], x - 1 });
    50                 s += a[x - 1] - y - 1;
    51                 a[x - 1] = y + 1;
    52                 se.insert({a[x - 1], x - 1 });
    53             }
    54         }
    55         if(x + 1 <= n) {
    56             if(a[x + 1] > y + 1) {
    57                 se.erase({a[x + 1], x + 1 });
    58                 s += a[x + 1] - y - 1;
    59                 a[x + 1] = y + 1;
    60                 se.insert({a[x + 1], x + 1 } );
    61             }
    62         }
    63     }
    64     //for (int i = 1; i <= n; i++)
    65     //    cout << i  << " " << a[i] << endl;
    66     ll ts = 0;
    67     for (int i = 1; i <= n; i++)
    68         ts += a[i];
    69     ll res = INT_MAX;
    70     for (int i = 1; i <= n; i++) {
    71         res = min(res, ts - a[i] * a[i]);
    72     }
    73     printf("%lld
    ", s + res);
    74  
    75 }
    76  
    77 int main() {
    78     //freopen("test.in", "r", stdin);
    79     //freopen("test.out", "w", stdout);
    80     int _;
    81     scanf("%d", &_);
    82     while(_--)
    83     solve();
    84     return 0;
    85 }
    View Code

    4. 连续的蛇,这个题写出目标方程,很容易简化为就是一个区间求一个点, 使得这些点到目标n个点的差的绝对值和最小。显然是一个二分问题,应该是凹的,但是,是整数上的,所以,用二分很容易做。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 1e5 + 10;
     7  
     8 int n;
     9 ll l, a, b;
    10 ll s[maxn];
    11  
    12 ll work(ll x) {
    13     ll r = 0;
    14     for (int i = 0; i < n; i++)
    15         r += abs(s[i] - x);
    16     return r;
    17 }
    18 void solve() {
    19     scanf("%d%lld%lld%lld", &n, &l, &a, &b);
    20     for (int i = 0; i < n; i++) {
    21         scanf("%lld", &s[i]);
    22     }
    23     sort(s, s + n);
    24     for (int i = 0; i < n; i++)
    25         s[i] -= i * l;
    26     //sort(s, s + n);
    27     ll left = a, right = b - n * l;
    28     ll ta = left, tb = right;
    29     while(left < right) {
    30         ll mid = (left + right) / 2;
    31         ll x1 = work(mid - 1), x2 = work(mid), x3 = work(mid + 1);
    32         if(x2 <= x1 && x2 <= x3) {
    33             left = right = mid;
    34         } else if(x1 <= x2 && x2 <= x3) {
    35             right = mid - 1;
    36         } else {
    37             left = mid + 1;
    38         }
    39         //cout << left << " " << right << endl;;
    40     }
    41     if(left < ta) left = ta;
    42     if(left > tb) left = tb;
    43     printf("%lld
    ", work(left));
    44  
    45 }
    46  
    47 int main() {
    48     //freopen("test.in", "r", stdin);
    49     //freopen("test.out", "w", stdout);
    50     int t;
    51     scanf("%d", &t);
    52     while(t--)
    53     solve();
    54     return 0;
    55 }
    View Code

    5. 保卫毒药,就是一个区间问题,注意到一条蛇,只会贡献水平或者垂直二选一,不能同时贡献。 然后先区分水平和垂直的线段, 然后转化为一维问题, 有一些线段, 求使得覆盖目标区间,最少需要多少线段。这个题目应该是比较

    简单的吧,排序,然后遍历一般就可以了。 我手残,居然错了好几次。果然以前想的不明白,写的不熟练。

    代码写的很丑的。

      1 #include<bits/stdc++.h>
      2 #define pb push_back
      3 typedef long long ll;
      4 using namespace std;
      5 typedef pair<int, int> pii;
      6 const int maxn = 1e5 + 10;
      7  
      8 int n, k, m;
      9 int a[maxn][4];
     10 int tleft, tright;
     11 bool check(int x, int y, int x1, int y1) {
     12     //cout << x << " " << y << " " << x1 << " " << y1 << endl;
     13     if(y < x1 || x > y1) return 0;
     14     return 1;
     15 }
     16 int res;
     17 bool f1, f2;
     18 void work(vector<pii> & v, bool &f) {
     19     f = 0;
     20     if(v.size() == 0 || v[0].first > tleft) {
     21         f = 1;
     22         return;
     23     }
     24     int cur = tleft, r = tleft;
     25     int cnt = 0;
     26     int x, y;
     27     bool in = 0;
     28     for (int i = 0; i < v.size(); i++) {
     29         x = v[i].first, y = v[i].second;
     30         //cout << x << " " << y << " " << cur << " " << r << endl;
     31         if(x > r + 1) {
     32             f = 0; return;
     33         }
     34         if(x <= cur) {
     35             if(y >= r) {
     36                 in = 1;
     37                 r = y;
     38             }
     39             if(i == v.size() - 1 && in) {
     40                 cnt++;
     41                 r++;
     42             }
     43         } else {
     44             cnt++;
     45             r++;
     46             if(r > tright) break;
     47             cur = r; in = 0;
     48             i--;
     49         }
     50  
     51     }
     52     //cnt++;
     53     if(r <= tright) f = 1;
     54     //cout << "r " << r << endl;
     55     //cout << "cnt " << cnt << endl;
     56     res += cnt;
     57 }
     58 void solve() {
     59     scanf("%d%d%d", &n, &k, &m);
     60     f1 = f2 = 0;
     61     for (int i = 0; i < m; i++) {
     62         for (int j = 0; j < 4; j++)
     63             scanf("%d", &a[i][j]);
     64     }
     65     res = 0;
     66     tleft = (n - k) / 2 + 1;
     67     tright = tleft + k - 1;
     68     //cout << tleft << " ads " << tright << endl;
     69     vector<pii> v1, v2;
     70     for (int i = 0; i < m; i++) {
     71         int x, y;
     72         x = min(a[i][0], a[i][2]);
     73         y = max(a[i][0], a[i][2]);
     74         if(check(x, y, tleft, tright)) {
     75             //cout << x << " c1 " << y << endl;
     76             v1.pb({x, y});
     77         }
     78         x = min(a[i][1], a[i][3]);
     79         y = max(a[i][1], a[i][3]);
     80         if(check(x, y, tleft, tright)) {
     81  
     82             v2.pb({x,y});
     83         }
     84     }
     85     sort(v1.begin(), v1.end());
     86     v1.erase(unique(v1.begin(), v1.end()), v1.end());
     87     sort(v2.begin(), v2.end());
     88     v2.erase(unique(v2.begin(), v2.end()), v2.end());
     89     work(v1, f1);
     90     //cout << "asd" <<endl;
     91     work(v2, f2);
     92     if(f1 || f2) {
     93         puts("-1");
     94     } else {
     95         printf("%d
    ", res);
     96     }
     97 }
     98  
     99 int main() {
    100     //freopen("test.in", "r", stdin);
    101     //freopen("test.out", "w", stdout);
    102     int _;
    103     scanf("%d", &_);
    104     while(_--)
    105     solve();
    106     return 0;
    107 }
    108  
    View Code

    6. 不会做。 后来发现,题目都没有仔细阅读,条件都没想清楚。 有时间看一下别人的题解吧。

    Pre-elimination round B。 也开始了,但是round a过了,就不让做b了,我也没有看。就这样吧。

    看的别人的代码,就是先把点移动到左上角,然后一次做删除, 删除每一行。注意边界条件。

      1 #include<bits/stdc++.h>
      2 #define pb push_back
      3 typedef long long ll;
      4 using namespace std;
      5 typedef pair<int, int> pii;
      6 const int maxn = 1e3 + 10;
      7 int n, m;
      8 string s;
      9 vector<pair<pii, pii>> ans;
     10 void print(pair<pii, pii> t) {
     11     cout << t.first.first << " " << t.first.second << " " << t.second.first << " " << t.second.second << endl;
     12 }
     13 void moveToTopLeft(int x, int y) {
     14     for (int i = y - 1; i > 0; i--) {
     15         ans.pb({{x, i}, {x, i + 1}});
     16     }
     17     for (int i = x - 1; i > 0; i--) {
     18         ans.pb({{i, 1}, {i + 1, 1} });
     19     }
     20 }
     21 void playrow(int x) {
     22     for (int i = 3; i <= m; i++) {
     23         ans.pb({{x, i}, {x, i - 2} });
     24         ans.pb({{x, i - 2}, {x, i - 1}});
     25         ans.pb({{x, i - 1}, {x, i} } );
     26     }
     27 }
     28 
     29 void playcol(int x) {
     30     for (int i = 3; i <= n; i++) {
     31         ans.pb({{i, x}, {i - 2, x} });
     32         ans.pb({{i - 2, x}, {i - 1, x} });
     33         ans.pb({{i - 1, x}, {i, x} });
     34     }
     35 }
     36 void solve() {
     37     cin >> n >> m;
     38     int x, y;
     39     x = y = 0;
     40     ans.clear();
     41     for (int i = 1; i <= n; i++) {
     42         cin >> s;
     43         for (int j = 1; j <= m; j++) {
     44             if(s[j - 1] == '.') {
     45                 x = i; y = j;
     46             }
     47         }
     48     }
     49     if(n * m == 2) {
     50         puts("0");
     51         return;
     52     }
     53     if(n < 3 && m < 3) {
     54         puts("-1");
     55         return;
     56     }
     57     moveToTopLeft(x, y);
     58     if(m == 1) {
     59         playcol(1);
     60     } else if(m == 2) {
     61         playcol(1);
     62         ans.pb({{1, 2}, {1, 1} });
     63         ans.pb({{3, 2}, {1, 2} });
     64         ans.pb({{1, 2}, {2, 2} });
     65         ans.pb({{2, 2}, {3, 2} });
     66         ans.pb({{1, 1}, {1, 2} });
     67         ans.pb({{1, 2}, {2, 2} });
     68         playcol(2);
     69         ans.pb({{n, 2}, {n - 1, 2} });
     70         ans.pb({{n - 1, 2}, {n - 1, 1} });
     71         ans.pb({{n, 1}, {n - 2, 1} });
     72     } else {
     73         playrow(1);
     74         for (int i = 2; i <= n; i++) {
     75             ans.pb({{i, 1}, {i - 1, 1} });
     76             ans.pb({{i, 3}, {i, 1} });
     77             ans.pb({{i, 1}, {i, 2} });
     78             ans.pb({{i, 2}, {i, 3} });
     79             ans.pb({{i - 1, 1}, {i, 1} } );
     80             ans.pb({{i, 1}, {i, 2} } );
     81             playrow(i);
     82         }
     83         if(n == 1) {
     84 
     85         } else if(n == 2) {
     86             ans.pb({{2, m}, {2, m - 1} });
     87             ans.pb({{2, m - 1}, {1, m - 1}  });
     88             ans.pb({{1, m}, {1, m - 2} });
     89         } else {
     90             ans.pb({{1, m}, {1, m - 1} });
     91             ans.pb({{1, m - 1}, {2, m - 1} });
     92             ans.pb({{2, m}, {2, m - 2} });
     93             ans.pb({{2, m - 2}, {2, m - 1} });
     94             ans.pb({{2, m - 1}, {2, m} });
     95             playcol(m);
     96         }
     97     }
     98     cout << ans.size() << endl;
     99     for (auto t : ans)
    100         print(t);
    101 }
    102 
    103 int main() {
    104     freopen("test.in", "r", stdin);
    105     //freopen("test.out", "w", stdout);
    106     int _;
    107     cin >> _;
    108     while(_--)
    109     solve();
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    ZOJ 3795 Grouping
    ZOJ 3791 An Easy Game
    ZOJ 3790 Consecutive Blocks
    POJ 1451 T9
    POJ 1141 Brackets Sequence
    POJ 2411 Mondriaan's Dream
    POJ 2513 Colored Sticks
    Eclipse 快捷键大全
    C# lock关键字(多线程)
    C# 内部类
  • 原文地址:https://www.cnblogs.com/y119777/p/6931088.html
Copyright © 2011-2022 走看看