当前位置: 代码迷 >> 综合 >> Codeforces Round #775 (Div. 2, based on Moscow Open Olympiad in Informatics) 题解
  详细解决方案

Codeforces Round #775 (Div. 2, based on Moscow Open Olympiad in Informatics) 题解

热度:57   发布时间:2023-11-30 14:29:23.0

A. Game

  • 思路
    • 只能跳一次!!!!
    • 从左和从右开始找到第一个0,然后相减+2(从0回到上一格的1陆地)即可
  • 经验教训
  • AC代码

#define int long long
const int maxn = 2e5 + 10;
int a[maxn];void solve(){
    int n;cin>>n;int ans = 0;int flagz = 0;for (int i = 1; i <= n; ++i) {
    int x;cin>>x;a[i] = x;if (x==0) flagz = 1;}int right = 0,left = 0;if (flagz==0) cout<<0<<'\n';else{
    for (int i = n; i > 1 ; --i) {
    if (a[i]==0) {
     right = i+1;break;}}for (int i = 1; i <= n; ++i) {
    if (a[i]==0){
    left = i-1;break;}}cout<<right-left<<'\n';}
}signed main() {
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int t;cin>>t;for (int i = 0; i < t; ++i) {
    solve();}}

B. Game of Ball Passing

  • 思路
    • 直接贪心,如果传球次数最多的那个人传球的数量比其他所有人的数量之和都多,他就一定得传空球(他传给别人别人不传给他),其他情况都可以一个球互相传解决
  • 经验教训
  • AC代码

#define int long long
const int maxn = 2e5 + 10;
int a[maxn];bool cmp(int aa,int bb){
    return aa>bb;
}
int dp[maxn];
void solve(){
    int n;cin>>n;int flagz = 0;int sum = 0;int maxx = 0;for (int i = 0; i < n; ++i) {
    int x;cin>>x;a[i] = x;sum+=x;maxx = max(maxx,x);if (x!=0) flagz = 1;}if (!flagz) {
     cout << 0 << '\n';return; }if (maxx > sum-maxx){
    cout<<maxx-(sum-maxx)<<'\n';}else cout<<1<<'\n';
}signed main() {
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int t;cin>>t;for (int i = 0; i < t; ++i) {
    solve();}}

C. Weird Sum

  • 思路
    • 分行和分列考虑,假设颜色ci只出现在第1行,第5行,第6行,第9行,那么只考虑x的曼哈顿距离就是(5-1+6-1+9-1)+(6-5+9-5)+(9-6),这一段逻辑对应代码的第11-20行
    • 接下来考虑如何得到每一种颜色出现在的行和列,我们预先定义vector row[maxn],row【k】这个vector里面存放的是每个k出现的行数(如果第x行出现了2的k,那就会有两个x,不矛盾)我们在读入数据的时候,读到一个ck,就将它对应的行row【ck】中,列同理。
    • 接下来只需对1-100000的i对应的row【i】和col【i】进行代码11-20行对应操作即可
  • 经验教训
  • AC代码
#define int long long
const int maxn = 1e5 + 10;vector<int> row[maxn];
vector<int> col[maxn];int count(vector<int> &color){
    sort(color.begin(),color.end());int sum = 0;int sz = color.size();for (int i = 1; i < sz; ++i) {
    sum+=color[i];}int n = sz-1;int ans = 0;for (int i = 0; i < sz-1; ++i) {
    ans += (sum-(n*color[i]));sum -= color[i+1];n--;}return ans;
}signed main() {
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int n,m;cin>>n>>m;for (int i = 1; i <=n ; ++i) {
    for (int j = 1; j <=m ; ++j) {
    int x;cin>>x;row[x].push_back(i);col[x].push_back(j);}}int ans = 0;for (int i = 1; i <= 100000 ; ++i) {
    ans+=(count(row[i])+ count(col[i]));}cout<<ans;

D. Integral Array

  • 思路
    • 对于数组中出现的某个i,如果【ij,ij+i-1】中的数出现在了数组中,且j并没有出现在数组中,那么数组非法
    • 只需要第一层for遍历i,第二层遍历合法j(i*j≤c的j即为合法j),查看是否出现不合法情况即可
  • 经验教训
  • AC代码
#define int long long
const int maxn = 1e6 + 10;inline void solve() {
    int n, c;cin >> n >> c;vector<int> sum(c+1);vector<int> cnt(c+1);int flago = 0;for (int i = 1; i <= n; ++i) {
    int x;cin >> x;if (x == 1) flago = 1;cnt[x]++;}if (!flago) {
    cout << "NO" << '\n';return;}for (int i = 1; i <= c; ++i) {
    sum[i] = sum[i - 1] + cnt[i];}for (int i = 1; i <= c; ++i) {
     // a[i]是选定的某个数if (!cnt[i]) continue;int num = c / i; // num是所有合法的倍数for (int j = 2; j <= num; ++j) {
     // j是倍数int right = min(c, i * j + i - 1);int left = i * j;if (sum[right] - sum[left - 1] > 0 && cnt[j] == 0) {
    cout << "NO" << '\n';return;}}}cout << "YES" << '\n';
}signed main() {
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int t;cin >> t;for (int i = 0; i < t; ++i) {
    solve();}
}
  相关解决方案