SMU Autumn 2024 Personal Round 2

SMU Autumn 2024 Personal Round 2

2024.9.22 12:00————15:20

过题数4/8
补题数5/8

  • Not Adjacent Matrix
  • Alyona and Numbers
  • Pleasant Pairs
  • Hossam and Friends
  • Same Count One
  • Shuffling Songs
  • The Harmonization of XOR
  • Division + LCP (hard version)

A - Not Adjacent Matrix

题解:
t组数据,每组数据给出一个数字n,要求输出一个n* n的数字矩阵,每个数字的上下左右的数字不能是与自己相差为1的数字,不重复得将数字1到n* n填充在矩阵中。
可以想象,如果将每个矩阵的右下角定为(n-1) * ( n-1)+1,从此开始的到n * n的数字交替分布在最右一列,最下一行。那么一定可以满足条件。注意当n等于2和n等于1的特殊情况。
也可以按奇偶分布。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int a[110][110];

void solve() {
    int n;
    cin >> n;
    a[0][0] = 2;a[0][1] = 9;a[0][2] = 7;
    a[1][0] = 4;a[1][1] = 6;a[1][2] = 3;
    a[2][0] = 1;a[2][1] = 8;a[2][2] = 5;
    for (int i = 3; i < 105; i++) {
        int ls =i*i+1;
        a[i][i] = ls++;
        for (int j = 0; j < i; j++) {
            a[i][j] = ls++;
            a[j][i] = ls++;
        }
    }
    if(n == 1) cout << 1 << endl;
    else if(n == 2) cout << -1 << endl;
    else {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cout << a[i][j] << ' ';
            }cout << endl;
        }
    }
    return ;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
       cin >> t;
    while(t--) {
        solve();
    }
    return 0;
}

B - Alyona and Numbers

题解:
给出n和m,n代表有一个从1到n的数组,m代表有一个从1到m的数组,从其中任取俩个数字配成一对,问有多少对的和可以被5整除。
以数字较小的b为切入口,与b配对后的和的范围是b+1到b+a,遍历一遍b加上配对后的范围的满足条件数即可。
代码:

#include <iostream>
#include <set>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<string.h>

using namespace std;
#define int long long
int x,y;

void solve() {
    cin >> x >> y;
    int a = x > y ? x : y;
    int b = x > y ? y : x;
    int ans = 0;
    for (int i = 1; i <= b; i++) {
        int mi = i;
        int ma = i+a;
        ans += (ma/5-mi/5);
//        cout << ma << ' ' << mi << endl ;
//        cout << ans << endl;
    }cout << ans << endl;

    return ;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
  //    cin >> t;
    while(t--) {
        solve();
    }
    return 0;
}


C - Pleasant Pairs

题解:
t组数据,每组给出一个包含n个数字的数组a,满足数字不重复且小于n * 2,问其中有多少对(i,j)满足ai * aj=i+j,要求i<j。
遍历数组a,先固定a[i],开始寻找2 * a[i],3 * a[i]…,看看2,3…对应的位置是否满足要求,超出范围直接break。因为这样找出来相当于每个i都找到了属于自己的j,所以要➗2。
代码:

#include <iostream>
#include <set>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<string.h>
#include<map>

using namespace std;
#define int long long
const int N = 1e5+10;
int ans = 0;
int n;
int a[N];
map<int,int>mp;

void solve() {
    ans = 0;
    cin >> n;
    for (int i = 1; i <= 2*n; i++) mp[i] = -1;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        mp[a[i]] = i;
    }
    for (int i = 1; i <= n; i++) {
        int res = a[i];
        int aj = 1;
        while(res <= i+n && aj <= 2*n) {
            if(mp[aj] != -1) {
                int wz = mp[aj];
                if(res == i+wz && i != wz) {
     //              cout << i << ' ' << wz << endl;
                    ans++;
                }
            }
            res += a[i];
            aj++;
        }
    }cout << ans/2 << endl;
    return ;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
     cin >> t;
    while(t--) {
        solve();
    }
    return 0;
}

D - Hossam and Friends

题解:
t组数据,每组数据给出n个人,m对关系,m对关系里的x,y互相不喜欢,问在这n个人里,有多少组连续的人互相喜欢,自己也算一组。
数组a中储存每个人讨厌的人中离自己最近的。然后从最后一个往前遍历,如果后面那个人讨厌的人比自己讨厌的人离得更近,就把自己讨厌的最近的人定义成后面那个人讨厌的人,接着在这个区间内的所有组都是满足条件的。
代码:

#include <iostream>
#include <set>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<string.h>
#include<map>

using namespace std;
#define int unsigned long long
#define endl "\n"
const int N = 1e6+10;
int n,m;

void solve() {
    int a[N];
    cin >> n >> m;
    int ans = n;
    for (int i = 1; i <= 100005; i++) a[i] = n+1;
    for (int i = 0; i < m; i++) {
        int x,y;
        cin >> x >> y;
        if(y > x) a[x] = min(a[x],y);
        if(x > y) a[y] = min(a[y],x);
    }
    for (int i = n-1; i >= 1; i--) {
        if(a[i] > a[i+1]) a[i] = a[i+1];
//        cout << a[i] << ' ';
        ans += (a[i]-i-1);
    }
//    for (int i = 1; i <= n; i++) {
        if(a[i] == n+1) {
            cout << n-i << ' ';
            ans += n-i;
            continue;
        }
        for (int j = a[i]-1; j >= i; j--) {
            a[i] = min(a[i],a[j]);
            a[j] = min(a[i],a[j]);
            ans += (a[j]-j-1);
        }
//if(a[i-1] > a[i]) {
//
//}
//        for (int j = i; j < a[i]; j++) {
//            a[i] = min(a[i],a[j]);
//        }
//        //     cout << a[i]-i-1 << ' ';
//        ans += (a[i]-i-1);
//    }
    cout << ans << endl;
    return ;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin >> t;
    while(t--) {
        solve();
    }
    return 0;
}

E - Same Count One

题解:
t组数据,给定n行m列的数组a,a中只包含0,1俩个数字。可以在同一列中任意交换俩个数字,如果可以实现每行中的1的个数相等,输出操作,否则输出-1。
先遍历每一行,记录它是多了多少或者是少了多少,然后遍历每一列,有人多有人少,就记录一下,然后输出交换。并记得更改状态。
代码:

#include <iostream>
#include <set>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<string.h>
#include<map>

using namespace std;
#define int long long
#define endl "\n"
const int N = 1e5+10;
string s[N];
int n,m;
int jia[N],ji[N];
int st[N];

void solve() {
    memset(st,0,sizeof st);
    cin >> n >> m;
    int ii = 0,jj = 0;
    int res = 0;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        string ss;
        for (int j = 0; j < m; j++) {
            int ls;
            cin >> ls;
            if(ls == 1) {
                res++;
                st[i]++;
            }
            ss += (ls+'0');
        }
        s[i] = ss;
    }
    if(res % n != 0) {
        cout << -1 << endl;
        return ;
    }
    int nm = res/n;
    for (int i = 0; i < n; i++) {
        //    cout << st[i] << ' ';
        if(st[i] > nm) {
            ans += st[i]-nm;
        }
    }
    cout << ans << endl;
    for (int i = 0; i < m; i++) {
        vector<int>a,b;
        for (int j = 0; j < n; j++) {
            if(s[j][i] == '1' && st[j] > nm) a.push_back(j);
            if(s[j][i] == '0' && st[j] < nm) b.push_back(j);
        }
 //       cout << a.size() << ' ' << b.size() << '/' << endl;
        for (int j = 0; j < min(a.size(),b.size()); j++) {
            cout << b[j]+1 << ' ' << a[j]+1 << ' ' << i+1 << endl;
            st[a[j]]--;
            st[b[j]]++;
        }
    }
    return ;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin >> t;
    while(t--) {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值