CF1091

CF1091A

水题。去个 \(\min\) 即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define inl inline
const int N=4e6+5;
const int M=1e5+5;
const int mod=1e5+3;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0){x=-x;putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar('\n');}
int y,b,r;

signed main(){
    y=read();b=read()-1;r=read()-2;
    writel(min(y,min(b,r))*3+3);
    return 0;
}

CF1091B

正解:把所有数加起来除以 \(n\)就是答案()

我的zz做法:枚举向量,求出加上第一个点后终点坐标,再对于其它点看向量是否存在

复杂度 \(O(n^2\log n)\) 稳居最劣解()

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define inl inline
const int N=1e5+5;
const int M=1e5+5;
const int mod=1e5+3;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0){x=-x;putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar('\n');}
int n,x[N],y[N],a[N],b[N];
map<pair<int,int>,int>mp;
signed main(){
    n=read();
    for(int i=1;i<=n;i++)x[i]=read(),y[i]=read();
    for(int i=1;i<=n;i++)a[i]=read(),b[i]=read();
    for(int i=1;i<=n;i++){
        int tx=x[1]+a[i],ty=y[1]+b[i];
        mp.clear();int flag=0;
        for(int i=1;i<=n;i++)mp[{a[i],b[i]}]++;
        for(int i=2;i<=n;i++){
            int aa=tx-x[i],bb=ty-y[i];
            if(!mp[{aa,bb}]){flag=1;break;}
            mp[{aa,bb}]--;
        }
        if(flag)continue;
        writei(tx);writel(ty);
    }
    return 0;
}

CF1091C

手玩样例会发现一件事:对于 \(n\) 的因数 可能会跳过几个同学 其他情况都和1一样 每个人都跳

每种情况的答案是一个等差数列 可以 \(O(1)\) 求出结果

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define inl inline
#define int ll
const int N=1e5+5;
const int M=1e5+5;
const int mod=1e5+3;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0){x=-x;putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar('\n');}
int n;
vector<int>v;
signed main(){
    n=read();
    for(int i=1;i*i<=n;i++){
        if(n%i)continue;
        v.push_back(i);
        if(i*i^n)v.push_back(n/i);
    }
    sort(v.begin(),v.end(),greater<int>());
    for(auto i:v)writei((n-i+2)*n/2/i);
    return 0;
}

CF1091D

题意:

给定整数 \(n\) ,把所有 \(1\)\(n\) 的排列按字典序拼成长为 \(n\)·\(n!\) 的序列。

求出有多少个长度为 \(n\) 、和为 \(n(n+1)/2\) 的连续子列,答案对素数 \(998244353\) 取模。

solution:

首先,长度为 \(n\) 、和为 \(n(n+1)/2\) 的连续子列 很显然就是满足 \(n\) 个数中 \(1...n\) 各出现一次的序列(依据题意不会出现其他情况)

那么我们考虑 \(n=3\) 的情况:

\[\underline{123}\ \underline{132}\ \underline{213}\ \underline{231}\ \underline{312}\ \underline{321} \]

\[1\underline{23\ 1}32\ 2\underline{13\ 2}31\ 3\underline{12\ 3}21 \]

我们可以按第一位是否相同 把序列分成 \(n\)

那么求的就是每一段内 以 \(1、2、3...n\) 每一位为开头 接下来 \(n\) 个数满足条件的个数 最后答案乘 \(n\)

然后我们可以发现 以 \(1、3...n\) 为开头的答案与 \(f_{i-1}\) 相同(看做去掉每个数开头的1)

第二位开头的情况 发现除了最后一个位置越界 其他都满足 答案 \((n-1)!-1\)

递推式 \(f_i=i\times(f_{i-1}+(i-1)!-1)=i\times f_{i-1}+i!-i\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define inl inline
#define int ll
const int N=1e6+5;
const int M=1e5+5;
const int mod=998244353;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0){x=-x;putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar('\n');}
int n,f[N],fac;
signed main(){
    n=read();
    f[1]=1;fac=1;
    for(int i=2;i<=n;i++)f[i]=(i*f[i-1]%mod+(fac=fac*i%mod)-i+mod)%mod;
    writel(f[n]);
    return 0;
}
posted @ 2023-11-02 13:59  xiang_xiang  阅读(314)  评论(0)    收藏  举报