Comet OJ - Contest #4

A
暴力

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <map>
using namespace std;

map<int, int> mp;
int main()
{
    int t;
    cin >> t;
    while(t--) {
        int ans, cnt = 0;
        mp.clear();
        for(int i = 0; i < 5; ++i) {
            int x;
            cin >> x;
            mp[x]++;
            if(mp[x] > cnt || (mp[x] == cnt && x < ans)) {
                ans = x;
                cnt = mp[x];
            }
        }
        cout << ans << endl;
    }
}

B
打表找规律,k分为偶数和奇数情况

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t;
    cin >> t;
    while(t--) {
        ll l, r, k;
        cin >> l >> r >> k;
        ll ans = 0;
        if(k & 1) {
            cout << r - l + 1 << endl;
        }
        else {
            if(l > k) {
                cout << r - l + 1 - (r - k) / (k + 1) + (l - k - 1) / (k + 1) << endl;
            }
            else if(r < k) {
                cout << r - l + 1 << endl;
            }
            else {
                cout << r - l - (r - k) / (k + 1) << endl;
            }
        }
    }
}

C
暴力枚举a和b的可能,用前缀和记录保存矩阵内1的数量,每个块内1的数量即为sum/(a+1)(b+1),判断可行性即可

#include <cstdio>
#include <vector>

const int N = 1000 + 10;

char s[N][N];
int g[N][N];

int main() {
  int T;
  scanf("%d", &T);
  for (int cas = 1; cas <= T; ++cas) {
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; ++i) {
      scanf("%s", s[i] + 1);
    }
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= m; ++j) {
        g[i][j] = g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1] + (s[i][j] == '0');
      }
    }
    if (g[n][m] == 0) {
      for (int i = 1; i <= k; ++i) {
        printf("%d%c", i, " \n"[i == k]);
      }
      continue;
    }
    std::vector<int> ret;
    for (int a = 0; a <= k && a <= n - 1; ++a) {
      int b = k - a;
      if (b < 0 || b > m - 1) continue;
      if (g[n][m] % ((a + 1) * (b + 1))) continue;
      std::vector<int> xs, ys;
      int col_sum = g[n][m] / (b + 1);
      int row_sum = g[n][m] / (a + 1);
      int avg = g[n][m] / ((a + 1) * (b + 1));
      for (int i = 0, j = 0; i <= m; ++i) {
        if (g[n][i] % col_sum == 0 && g[n][i] / col_sum == j) {
          ys.push_back(i);
          ++j;
        }
      }
      if (ys.size() != b + 2) continue;
      ys.pop_back(); ys.push_back(m);
      for (int i = 0, j = 0; i <= n; ++i) {
        if (g[i][m] % row_sum == 0 && g[i][m] / row_sum == j) {
          xs.push_back(i);
          ++j;
        }
      }
      if (xs.size() != a + 2) continue;
      xs.pop_back(); xs.push_back(n);
      bool valid = true;
      for (size_t i = 1; i < xs.size() && valid; ++i) {
        for (size_t j = 1; j < ys.size() && valid; ++j) {
          int sum = g[xs[i]][ys[j]] - g[xs[i]][ys[j - 1]] - g[xs[i - 1]][ys[j]] + g[xs[i - 1]][ys[j - 1]];
          valid &= (sum == avg);
        }
      }
      if (valid) {
        std::vector<int> tmp;
        for (int i = 1; i <= a; ++i) tmp.push_back(xs[i]);
        for (int i = 1; i <= b; ++i) tmp.push_back(ys[i] + n - 1);
        if (ret.empty() || ret > tmp) ret = tmp;
      }
    }
    if (ret.empty()) puts("Impossible");
    else {
      for (int i = 0; i < k; ++i) {
        printf("%d%c", ret[i], " \n"[i == k - 1]);
      }
    }
  }
  return 0;
}

D
打表找规律,发现10个相加的和一定为45.处理1-x范围内的答案,即分为前能整除10的部分答案为(x/10)*45和后从(x/10)*10到x的部分。
暴力处理后半部分,f(x+i) % 10 = (f(x) + i) % 10

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
namespace io {
    const int SIZE = 1e7 + 10;
    char inbuff[SIZE];
    char *l, *r;
    inline void init() {
        l = inbuff;
        r = inbuff + fread(inbuff, 1, SIZE, stdin);
    }
    inline char gc() {
        if (l == r) init();
        return (l != r) ? *(l++) : EOF;
    }
    void read(int &x) {
        x = 0; char ch = gc();
        while(!isdigit(ch)) ch = gc();
        while(isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
    }
    void read(ll &x) {
        x = 0; char ch = gc();
        while(!isdigit(ch)) ch = gc();
        while(isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
    }
} using io::read;
int x[100], tot;
ll sum(ll a) {
    //if(a < 10) return (a + 1) * a / 2;
    ll res = (a / 10) * 45;
    ll b = (a / 10) * 10;
    while(true) {
        tot = 0;
        while(b) {
            x[tot++] = b % 10;
            b /= 10;
        }
        for(int i = tot - 1; i >= 1; --i) b = b * 10 + (x[i] + x[i - 1]) % 10;
        if(b < 10) break;
    }
    for(int i = 0; i <= a % 10; ++i) {
        res += (b + i) % 10;
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int t;
    read(t);
    while(t--) {
        ll l, r;
        read(l);
        read(r);
        printf("%lld\n", sum(r) - sum(l - 1));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值