2022 四川某化工大学新生赛

复建第一题,上去找找比赛打打,看见某校新生赛正在running就进来转转,反正回复下手感就得从初级题开始,几个月不练的帐也得给补上

A题,水题,切了

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (1000000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}


int n, m, k;
int a[limit];
int dp[limit];
void solve() {
    string str;
    cin>>str;
    str.reserve(4);
    reverse(str.begin(), str.end());
    while(str.length() < 4){
        str.push_back('0');
    }
    reverse(str.begin(), str.end());
    cout<<str<<endl;

}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
    FASTIO

//    int kase;
//    cin >> kase;
//    while (kase--)
        solve();
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
AC Code

B题,也就是简单模拟,没啥难度

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (1000000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}

#define int ull
int n, m, k;
int a[limit];
int dp[limit];
void solve() {
    ll ans = 0;
    cin>>n;
    per(i, 0, 63){
        if((1ull<<i) <= n) {

            cout<<i<<endl;
            break;
        }
    }

}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
    FASTIO

//    int kase;
//    cin >> kase;
//    while (kase--)
        solve();
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
AC Code

C题,给出一个n和k和一个01串,只能在1的地方落脚,一次最多走k格,问最小跳跃次数,这个就是很简单的dp,没什么难度

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (1000000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}

int n, m, k;
int a[limit];
int dp[limit];
void solve() {
    cin>>n>>k;
    string str;
    cin>>str;
    str = ' ' + str;
    fill(dp, dp + 1 + n, INF);
    dp[0] = dp[1] = 0;
    rep(i,1,n){
        if(str[i] == '0')continue;
        per(j, i - k, i - 1){
            if(j <= 0)break;
            if(str[j] == '0')continue;
            dp[i] = min(dp[i], dp[j] + 1);
        }
    }
    cout<<(dp[n] < INF ? dp[n] : -1)<<endl;
}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
    FASTIO

//    int kase;
//    cin >> kase;
//    while (kase--)
        solve();
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
AC Code

D题,给出一个数字n,要求给出n个互不相同的长度为2n的合法括号串,这个一开始想爆搜,后来模拟之后发现我们只需要维护当前有多少左括号即可,一个右括号是-1,一个左括号对于cnt的影响是+1,很显然如果要合法,那么cnt为0的时候我们只能放左括号,如果cnt大于0我们可以左括号和右括号都放,最后再判断一下长度就好了

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (100000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}

int n, m, k;
int a[limit];
vector<string>ans;
int tot;
void dfs(string str, int cnt){
    if(ans.size() >= n)return;
    if(str.length() == 2 * n && cnt == 0){
        ans.push_back(str);
        return;
    }
    if(str.length() >= 2 * n)return;
    if(cnt > 0){
        dfs(str + ')', cnt -  1 );
        dfs(str + '(', cnt + 1);
    }else if(cnt == 0){
        dfs(str + '(', cnt + 1);
    }else{
        return;
    }
}
void solve() {
    cin>>n;
    ans.clear();
    dfs("", 0);
    for(const auto & it : ans){
        cout<<it<<endl;
    }
}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
    FASTIO

    int kase;
    cin >> kase;
    while (kase--)
        solve();
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
View Code

E题,给一个函数f(x) = 大于x的最小质数,问g(x) = (f(x) + f(f(x))) / 2是否是质数

这个我以为是什么难题,但是想了下发现数字范围都在int128范围内,可以做。

我们预处理出来1e5范围内素数,然后就能用二分法 + 乘法快速求出f(x), 最后再用罗宾米勒算法判断是不是质数,但是需要注意,这题没法用phi,用phi铁超时,烦人

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (100000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef __int128 ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}
int num[limit];
int prime[limit],tot;
void make_prime(int N = 1e5){
    memset(num, 1, sizeof(num));
    num[1] = num[0] = 0;
    tot = 0;
    rep(i, 2,N){
        if(num[i])prime[++tot] = i;
        for(ll j = 1; j <= tot && i * prime[j] <= N; ++j){
            num[i * prime[j]] = 0;
            if(i % prime[j] == 0)break;//断开
        }
    }
}//欧拉筛
int n, m, k;
int a[limit];
ll f(ll x){
    auto it = upper_bound(prime + 1, prime + 1 + tot, x);
    if(it != prime + 1 + tot){
        return *it;
    }
    ll sum = 1;
    rep(i,1, tot){
        sum *= prime[i];
        if(sum > x)break;
    }
    return sum;
}
ll qpow(ll a, ll n, ll p) // 快速幂
{
    ll ans = 1;
    while (n)
    {
        if (n & 1)
            ans = (__int128)ans * a % p; // 注意!中间结果可能溢出,需要使用__int128过渡
        a = (__int128)a * a % p;
        n >>= 1;
    }
    return ans;
}
bool valid(ll x)
{
    if (x < 3) // 特判1,2
        return x == 2;
    if (x % 2 == 0) // 特判偶数
        return false;
    ll A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022}, d = x - 1, r = 0;
    while (d % 2 == 0) // 算出d, r
        d /= 2, ++r;
    // 或:r = __builtin_ctz(d), d >>= r;
    for (auto a : A)
    {
        ll v = qpow(a, d, x); // a^d
        // 如果a^d≡0,说明是a是x的倍数;如果a^d≡1或-1,说明这串数接下来一定都是1,不用继续计算
        if (v <= 1 || v == x - 1)
            continue;
        for (int i = 0; i < r; ++i)
        {
            v = (__int128)v * v % x; // 同样使用__int128过渡
            if (v == x - 1 && i != r - 1) // 得到-1,说明接下来都是1,可以退出了
            {
                v = 1;
                break;
            }
            // 在中途而非开头得到1,却没有经过-1,说明存在其他数字y≠-1满足y^2≡1,则x一定不是奇素数
            if (v == 1)
                return false;
        }
        if (v != 1) // 查看是不是以1结尾
            return false;
    }
    return true;
}
void solve() {
    ll x;
    x = read();
    auto ans = (f(x) + f(f(x))) / 2;

    if(valid(ans)){
        puts("YES");
    }else{
        puts("NO");
    }
}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
//    FASTIO
    make_prime();
    int kase;
    kase = read();
    while (kase--)
        solve();
//    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
AC Code

F题,给出一个01串,可以分成任意段,问mex的总和最小是多少

这个题其实不难,首先我们发现可以合并连续相同的段,然后判断最后是不是全是1或者全是0,如果不是的话,看看如果把1都单拿出来,0的贡献和2哪个小就行了(因为01串什么都不做,mex最大就是2)

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (100000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}
int n, m, k;
int a[limit];
void solve() {
    string str;
    cin>>str;
    string ans;
    for(auto it: str){
        if(ans.empty()){
            ans.push_back(it);
            continue;
        }
        if(ans.back() == it)continue;
        ans.push_back(it);
    }
    if(ans.length() == 1){
        cout<<(ans.back() == '0' ? 1 : 0)<<endl;
        return;
    }
    cout<<min(2, (int)count(ans.begin(), ans.end(), '0'))<<endl;
}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
    FASTIO
    int kase;
    cin>>kase;
    while (kase--)
        solve();
//    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
AC Code

 

H题,给出a和b,求最大最小的c,使得a mod c == b mod c,这题我似乎在哪见过,但想不起来,就是特判就好了,当两者相差为1的时候,不存在答案,其他的话就用差值或者看最小的是否为2,当a和b相同的时候,我们看看a和b能不能作为c,即c >= 1,如果可以的话就是2 a或者b, 如果不行的话就是-1 -1, 其他的话首先找到差值,另外从差值我们自然想到差值的因数应该也可以当作c,证明很简单,不列出,然后我们因式分解以下取最小的因子当作最小的c,差值当作大c就好了,如果是质数,那么就用差值当作上下界好了。其实我想到这个的原因是,1919810,这个样例味道太冲了,肯定在提示质数,所以就想到后面的了

坑点就是hdu系列的oj不能用cerr,我还以为哪写错了debug了半天。。。。

#include <bits/stdc++.h>
using namespace std;
constexpr int limit =  (100000 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a  ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;

inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    ll sign = 1, x = 0;
    char s = getchar();
    while (s > '9' || s < '0') {
        if (s == '-')sign = -1;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = (x << 3) + (x << 1) + s - '0';
        s = getchar();
    }
    return x * sign;
#undef getchar
}//快读
void print(ll x) {
    if (x / 10) print(x / 10);
    *O++ = x % 10 + '0';
}

void write(ll x, char c = 't') {
    if (x < 0)putchar('-'), x = -x;
    print(x);
    if (!isalpha(c))*O++ = c;
    fwrite(obuf, O - obuf, 1, stdout);
    O = obuf;
}

ll n, m, k;
int a[limit];
void solve() {
    cin>>n>>m;
    ll ans = llabs(n - m);

    if(n == m){
        if(n <= 1){
            cout<<-1<<" "<<-1<<endl;
        }else{
            cout<<2<<" "<<n<<endl;
        }
        return;
    }
    if(ans <= 1){
        cout<<-1<<" "<<-1<<endl;
        return;
    }
    for(int i = 2; i * i <= ans; ++i){
        if(ans % i == 0){
            cout<<i<<" "<<ans<<endl;
            return;
        }
    }
    cout<<ans<<" "<<ans<<endl;
}
int32_t main() {
#ifdef LOCAL
    FOPEN;
//    FOUT;
#endif
    FASTIO

    int kase;
    cin >> kase;
    while (kase--)
        solve();
//    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    return 0;
}
AC Code

写完就手工吧,下午搞一搞项目,今天的算法就到这里了

posted @ 2022-08-11 14:27  tiany7  阅读(24)  评论(0编辑  收藏  举报