2022年zzuli周赛(2)

消消乐

我们可以考虑贪心,想一想,如果\(s\)串和\(t\)串中有一个字母相同的话,是不是就相当于必然存在\(S,t\)相同(将两个字符串删减成一个字母就可以了)

C:

#include<stdio.h>
#include<string.h>
char s[1000001], t[1000001];
int v[52];
int main(){
    scanf("%s%s", s, t);

    int n = strlen(s), m = strlen(t);

    for(int i = 0; i < n; i++){
        if('a' <= s[i] && s[i] <= 'z')v[s[i] - 'a'] = 1;
        else v[s[i] - 'A' + 26] = 1;
    }

    for(int i = 0; i < m; i++){
        if('a' <= t[i] && t[i] <= 'z'){
            if(v[t[i] - 'a']){
                printf("YES");
                return 0;
            }
        }
        else{
            if(v[t[i] - 'A' + 26]){
                printf("YES");
                return 0;
            }
        }
    }
    printf("NO");
}

C++:

#include<bits/stdc++.h>
int main(){
    std::string s, t;
    std::cin >> s >> t;

    std::array<bool, 52> v{};
    for(int i = 0; i < s.size(); i++){
        if('a' <= s[i] && s[i] <= 'z')v[s[i] - 'a'] = 1;
        else v[s[i] - 'A' + 26] = 1;
    }

    for(int i = 0; i < t.size(); i++){
        if('a' <= t[i] && t[i] <= 'z'){
            if(v[t[i] - 'a']){
                std::cout << "YES";
                return 0;
            }
        }
        else{
            if(v[t[i] - 'A' + 26]){
                std::cout << "YES";
                return 0;
            }
        }
    }
    std::cout << "NO";
}

Amazing number!

  1. 直接循环判断
  2. 先判断这个数字是否是质数,再判断回文,然后累加到答案上

code:

C:

#include <stdio.h>
#include <stdlib.h>

int is_palindrome(int n) 
{
    int a = n, b= 0;
    while (n > 0) 
    {
        b = b * 10 + n % 10;
        n /= 10;
    }
    if (a == b)  return 1;
    else return 0;
}
int is_prime(int n)
{
    if(n<2) return 0;
    for(int i=2;i<=n/i;i++)
    {
        if(n%i==0) return 0;
    }
    return 1;
}
int main()
{
    int l,r;
    scanf("%d%d",&l,&r);
    int ans=0;
    for(int i=l;i<=r;i++)
    {
        if(is_prime(i)&&is_palindrome(i))
        {
            ans++;
        }
    }
    printf("%d\n",ans);
}

C++

#include <bits/stdc++.h>
using namespace std;
bool is_prime(int n)
{
    if(n<2) return false;
    for(int i=2;i<=n/i;i++)
    {
        if(n%i==0) return false;
    }
    return true;
}
bool is_palindrome(int n)
{
    string a=to_string(n);
    string b=a;
    reverse(b.begin(),b.end());
    if(a==b) return true;
    else return false;
}
void solve()
{
    int l,r;
    cin>>l>>r;
    int ans=0;
    for(int i=l;i<=r;i++)
    {
        if(is_prime(i)&&is_palindrome(i))
        {
            ans++;
        }
    }
    cout<<ans<<'\n';
}
int main()
{
    solve();
}

LeetCode 1

读题可以知道,如果前面两个出现的数字出现并且连续,那么相当于前面双周赛,否则,就是单周赛

C:

#include <stdio.h>

int a[15];
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    if (a[n] - a[n - 1] == 1) {
        printf("1\n");
    } else {
        printf("2\n");
    }
    return 0;
}

C++:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    vector<int> arr(n+1,0);
    for(int i=1;i<=n;i++) cin>>arr[i];
    if(arr[n]==arr[n-1]+1) cout<<1<<'\n';
    else cout<<2<<'\n';
}

scz的小难题

考虑到情况很多,可以先给\(a,b,c\)排一个序,对于\(a,b,c\)三种数字,如果将\(a\times b\)赋值给\(c\),然后再将\(a\times b\)赋值给\(a\),然后\(a,c\)相减,那么最多\(3\)步就可以将出现\(0\)了,所以答案最多是\(3\),然后其他可以分类情况进行讨论就可以了~~

  1. 如果其中有\(0\),那么答案就是\(0\)
  2. 如果\(a=b||b=c||a=c\) 那么答案就是1
  3. 如果\(a+b=c||a+a=b||a+a=c||b+b=c\) 答案就是2
  4. 如果\(a\times b=c||b\times c=c||a\times b=b\) 答案就是2
  5. 其余情况就是3

(注意有一个十分坑的数据:43073 99716 99972 不开\(long long 过不去\))

具体特殊样例可以看代码:

C:

#include <stdio.h>
#include <stdlib.h>
long long max(long long a,long long b,long long c)
{
    if(a>=b&&a>=c) return a;
    if(b>=a&&b>=c) return b;
    if(c>=b&&c>=a) return c;
}
long long min(long long a,long long b,long long c)
{
    if(a<=b&&a<=c) return a;
    if(b<=a&&b<=c) return b;
    if(c<=b&&c<=a) return c;
}
void solve()
{
    long long a,b,c;
    scanf("%lld%lld%lld",&a,&b,&c);
    long long maxn=max(a,b,c);
    long long minn=min(a,b,c);
    long long mid=a+b+c-maxn-minn;
    a=minn;
    b=mid;
    c=maxn;
    if(a==0||b==0||c==0) printf("0\n");
    else if(a==b||b==c||a==c) printf("1\n");//两个数字相同
    else if(a+b==c||a+a==b||a+a==c||b+b==c) printf("2\n");//两数相加等于另一个数字
    else if(a*b==c)  printf("2\n");// 2 3 6 相乘等于另一数字
    else if(b*c==c)  printf("2\n");// 1 1 5
    else if(a*b==b)  printf("2\n"); //1 5 6
    else printf("3\n");//其他情况 
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return (0^0);
}

C++:

#include <bits/stdc++.h>
using namespace std;
void solve()
{
    vector<long long> arr(3,0);
    sort(arr.begin(),arr.end());
    long long a=arr[0];
    long long b=arr[1];
    long long c=arr[2];
    if(a==0||b==0||c==0) cout<<"0"<<'\n';
    else if(a==b||b==c||a==c) cout<<1<<'\n';//两个数字相同
    else if(a+b==c||a+a==b||a+a==c||b+b==c) cout<<2<<'\n';//两数相加等于另一个数字
    else if(a*b==c) cout<<2<<'\n';// 2 3 6 相乘等于另一数字
    else if(b*c==c) cout<<2<<'\n';// 1 1 5
    else if(a*b==b) cout<<2<<'\n'; //1 5 6
    else cout<<3<<'\n';//其他情况 
}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//注意开解绑
    int T=1;
    cin>>T;
    while(T--) solve();
	return (0^0);
}

stO SCZ Orz

考虑到a的数字很大,所以不适合用普通的a%b来进行计算,如果你会java或者python,可以使用相关的大整数来进行计算,但是后台只开了1s时限,Java会超,Py数据会答案错误(zzuli的毛病, 所以说只能用C/C++(

考虑到 \((a+b)\mod c\)=\(a\mod c+b\mod c\)

可以根据秦九韶算法将\(a\)进行分解,比如 \(234=200+30+4\)分解,然后将

根据\((a+b)\mod c\)=\(a\mod c+b\mod c\)中,然后套入即可,

C:

#include <stdio.h>
#include <string.h>
#define N 1000010
const int mod=1e9+7;
char a[N];
int main()
{
    int b;
    scanf("%s%d",a,&b);
    long long ans=0;
    int n=strlen(a);
    for(int i=0;i<n;i++)
    {
        ans=(ans*10%b+(a[i]-'0'))%b;
    }
    printf("%lld",ans);
}

C++:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string a;
    int b;
    cin>>a>>b;
    long long ans=0;
    for(int i=0;i<a.size();i++)
    {
        ans=(ans*10%b+(a[i]-'0'))%b;
    }
    cout<<ans<<'\n';
}

LeetCode 2

考虑到\(n\leq 1000\) 所以说只要会冒泡排序就可以直接过了,注意一下怎么比较,然后排序就可以了~~

C:

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int name;
    int score;
    int time;
    int errorNumber;
}b[1001];
int a[5];
int main() {
    scanf("%d %d %d %d", &a[1], &a[2], &a[3], &a[4]);
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) 
    {
            b[i].name = i, b[i].time = -1, b[i].score = 0, b[i].errorNumber = 0;
        for (int j = 1; j <= 4; ++j) 
        {
            int x, y;
            scanf("%d %d", &x, &y);
            if (x == -1) {
                continue;
            }
            b[i].score += a[j];
            if (b[i].time < x) {
                b[i].time = x;
            }
            b[i].errorNumber += y;
        }
    }
    for (int i = 1; i <= n - 1; ++i) 
    {
        for (int j = 1; j <= n - i; ++j)
        {
            if (b[j].score < b[j + 1].score) 
            {
                struct node temp = b[j];
                b[j] = b[j + 1];
                b[j + 1] = temp;
            } else if(b[j].score == b[j + 1].score) 
            {
                int x = b[j].time + 20 * b[j].errorNumber;
                int y = b[j + 1].time  + 20 * b[j + 1].errorNumber;
                if(y < x) 
                {
                    struct node temp = b[j];
                    b[j] = b[j + 1];
                    b[j + 1] = temp;
                } else if(y == x)
                {
                    if(b[j + 1].name < b[j].name) 
                    {
                        struct node temp = b[j];
                        b[j] = b[j + 1];
                        b[j + 1] = temp;
                    }
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) {
        printf("%d ", b[i].name);
    }
    return 0;
}

C++:

#include <bits/stdc++.h>
using namespace std;
struct Node
{
    int id;
    int score;
    int last=0;
    int pently;
    int sum;
    bool operator <(const Node &other) const
    {
        if(score!=other.score) return score>other.score;
        if(sum!=other.sum) return sum<other.sum;
        return id<other.id;
    }
};
void solve()
{
    vector<int> score(5,0);
    for(int i=1;i<=4;i++) cin>>score[i];
    int n;
    cin>>n;
    vector<Node> arr(n+1);
    for(int i=1;i<=n;i++)
    {
        arr[i].id=i;
        for(int j=1;j<=4;j++)
        {
            int times,pently;
            cin>>times>>pently;
            if(times==-1) continue;
            arr[i].score+=score[j];
            arr[i].pently+=20*(pently);
            arr[i].last=max(arr[i].last,times);
        }
    }
    for(int i=1;i<=n;i++)
    {
        arr[i].sum=arr[i].last+arr[i].pently;
    }
    sort(arr.begin()+1,arr.end());
    for(int i=1;i<=n;i++) cout<<arr[i].id<<' ';
    cout<<'\n';
    

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

完美数

假设我们要找的数是 \(num\),我们发现只要一个数是合数,它就一定能写成 \(k*x\)\(x\) 是质数)的形式,若 \(gcd(num,x) \neq 1\),则定有 \(gcd(num,kx) \neq 1\),所以我们只需要考虑小于等于 \(n\) 的质数就可以了,让 \(num\) 与这些质数的最大公约数不等于 \(1\) 就行了,这个最小的 \(num\) 就是让这些质数相乘。

#include <stdio.h>
const int mod = 1e9 + 7;
int is_prime(int num){
  if(num == 1)return 0;
  for(int i = 2; i <= num / i; i++)
    if(num % i == 0)return 0;
  return 1;
}
int main()
{
  int n;
  scanf("%d", &n);
  int ans = 1;
  for(int i = 2; i <= n; i++)
  {
    if(is_prime(i))ans = (long long)ans * i % mod;
  }
  	printf("%d", ans);
}

C++:

#include <bits/stdc++.h>
constexpr int mod = 1e9 + 7;

bool is_prime(int num)
{
    if(num == 1)return 0;
    for(int i = 2; i <= num / i; i++)
    {
        if(num % i == 0)return 0;
    }
    return 1;
}

int main()
{
    int n;
    std::cin >> n;
    int ans = 1;
    for(int i = 2; i <= n; i++)
    {
        if(is_prime(i))ans = (long long)ans * i % mod;
    }
    std::cout << ans;
}

C++另一种写法 :

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int get(int n)
{
    for(int i=2;i<=n/i;i++)
    {
        if(n%i==0)
        {
            return i;
        }
    }
    return n;
}
void solve()
{
    int n;
    cin>>n;
    long long ans=1;
    map<int,int> mp;
    for(int i=2;i<=n;i++)
    {
        long long temp=get(i);
        if(!mp.count(temp))
        {
            mp[temp]++;
            ans=ans*temp%mod;
        }
    } 
    cout<<ans%mod<<'\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    // cin>>T;
    while(T--) solve();
    return (0^0);
}

数数 (easy version)

这里只要比较\(A_i\times A_j\leq A_i+A_j\)即可,发现只要分类讨论就可以了

这里为了更好的表达,原题转化成\(a\times b\leq a+b\)即可

  1. \(a,b\)中正负号相反,即一个是负数,一个是正数,满足题意
  2. 如果全部都是\(1\),那么也是符合的
  3. 如果是全部都是\(0\),那么也是符合的
  4. \(1\)和其他的正数也是符合条件的,
  5. 所有的\(2\)也是符合条件的
  6. 其余的情况,根据小学二年级的均值不等式,显然不成立~~

C:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const int mod=1e9+7;
#define N 1000010
int arr[N];
void solve()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
    int pos=0;
    int neg=0;
    for(int i=1;i<=n;i++)
    {
        if(arr[i]>0) pos++;
        else if(arr[i]<0) neg++;
    }
    long long ans=1ll*pos*neg%mod;
    int number1=0;
    int other=0;
    int number2=0;
    int number0=0;
    for(int i=1;i<=n;i++)
    {
        if(arr[i]==1) number1++;
        if(arr[i]==2) number2++;
        if(arr[i]!=1&&arr[i]>1) other++;
        if(arr[i]==0) number0++;
    }
    ans=(ans%mod+1ll*number1*(number1-1)/2%mod+mod)%mod;
    ans=(ans%mod+1ll*number0*(number0-1)/2%mod+mod)%mod;
    ans=(ans%mod+1ll*number1*other%mod+mod)%mod;
    ans=(ans%mod+1ll*number0*pos%mod+mod)%mod;
    ans=(ans%mod+1ll*number2*(number2-1)/2%mod+mod)%mod;
    printf("%lld\n",ans);
}
int main()
{
    int T=1;
    // cin>>T;
    while(T--) solve();
    return (0^0);
}

C++:

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
void solve()
{
    int n,k;
    cin>>n>>k;
    vector<int> arr(n+1,0);
    for(int i=1;i<=n;i++) cin>>arr[i];
    int pos=0;
    int neg=0;
    for(int i=1;i<=n;i++)
    {
        if(arr[i]>0) pos++;
        else if(arr[i]<0) neg++;
    }
    long long ans=1ll*pos*neg%mod;
    int number1=0;
    int other=0;
    int number2=0;
    int number0=0;
    for(int i=1;i<=n;i++)
    {
        if(arr[i]==1) number1++;
        if(arr[i]==2) number2++;
        if(arr[i]!=1&&arr[i]>1) other++;
        if(arr[i]==0) number0++;
    }
    ans=(ans%mod+1ll*number1*(number1-1)/2%mod+mod)%mod;
    ans=(ans%mod+1ll*number0*(number0-1)/2%mod+mod)%mod;
    ans=(ans%mod+1ll*number1*other%mod+mod)%mod;
    ans=(ans%mod+1ll*number0*pos%mod+mod)%mod;
    ans=(ans%mod+1ll*number2*(number2-1)/2%mod+mod)%mod;
    cout<<ans%mod<<'\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    // cin>>T;
    while(T--) solve();
    return (0^0);
}

数数 (hard version)

\(A_i*A_j<=A_i+A_j+K\)

化简一下 \(A_i<=1+\frac{K+1}{A_j-1}\)

枚举 \(A_j\) 即可

#include <bits/stdc++.h>
using namespace std;
#define ll long long
constexpr int mod = 1e9 + 7;
void solve(){
    int n, k = 0;
    cin >> n >> k;
    vector<int> a(n);
    for(int& i : a)cin >> i;

    ll ans = 0;

    for(int i = n - 1, cnt = 0; i >= 0; i--){
        ans = (ans + cnt) % mod;
        cnt += a[i] == 1;
    }

    for(int i = 2; i <= k + 2; i++){
        int lim = 1 + (k + 1) / (i - 1);
        for(int j = n - 1, cnt = 0; j >= 0; j--){
            if(a[j] <= lim)ans = (ans + cnt) % mod;
            cnt += a[j] == i;
        }
    }
    for(int i = n - 1, cnt = 0; i >= 0; i--){
        if(a[i] <= 1)ans = (ans + cnt) % mod;
        cnt += a[i] >= k + 3;
    }

    for(int i = 0; i >= -k; i--){
        int lim = 1 + (k + 1) / (i - 1);
        for(int j = n - 1, cnt = 0; j >= 0; j--){
            if(a[j] >= lim)ans = (ans + cnt) % mod;
            cnt += a[j] == i;
        }
    }
    for(int i = n - 1, cnt = 0; i >= 0; i--){
        if(a[i] >= 1)ans = (ans + cnt) % mod;
        cnt += a[i] <= -k - 1;
    }

    cout << ans << "\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    solve();
}

This is a very hard problem

阅读题意便知道,输出\(a+b\)即可,注意不要爆\(int\),开\(long long\)

C/C++:

#include <stdio.h>

int main()
{
    long long a,b;
    scanf("%lld%lld",&a,&b);
    printf("%lld",a+b);
}
posted @ 2022-10-30 17:46  Meteor_Z  阅读(186)  评论(0编辑  收藏  举报