week5

Day1

2023牛客寒假算法基础集训营4

A—清楚姐姐学信息论

思路:比较pow(x, y)和pow(y, x)大小

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

int main() {
    long long int a, g,n;
    cin >> a >> g;
   
    if (pow(a,g) <pow(g,a)) {
        cout << g << endl;
    } else if (pow(a,g) > pow(g,a)) {
        cout << a <<endl;
    }
    else cout<< min(a,g)<<endl;
    return 0;
}

 

 B-清楚姐姐学构造

思路:当m为2,且前后的c的和为奇数时不存在;先构造出a,为前后c的和的一半时可满足条件,(特判下前后c的和为奇数时,可能存在a同b不同的情况)再用c,a求出b;

#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e5+5;

int n,m;
ll c[N],a[N],b[N];

int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;++i)
        scanf("%lld",&c[i]);

    for(int i=0;i<n;++i){
        ll sum=c[i]+c[n-1-i];
        if(sum%2&&m==2){
            printf("No");
            return 0;
        }else if(sum%2) a[i]=((sum+m)/2)%m;
        else a[i]=(sum/2)%m;
    }
    for(int i=0;i<n;++i) b[i]=(((c[i]-a[i])%m)+m)%m;
    if(n%2){
        a[n/2]=c[n/2];
        b[n/2]=0;
    }
    printf("Yes\n");
    for(int i=0;i<n;++i) printf("%lld ",a[i]);
    cout<<endl;
    for(int i=0;i<n;++i) printf("%lld ",b[i]);
}

 

 

C—清楚姐姐学01背包(Easy Version)

思路:把除了第i个物品以外的物品打一个01背包,判断第i个物品是否必须取

#include <bits/stdc++.h>

using namespace std;
 
using LL = long long;

int main(){
    int T = 1;
    while(T--){
        int n,m;
        cin>>n>>m;
        vector<int> v(n+1),w(n+1);
        for(int i=1;i<=n;i++){
            cin>>w[i]>>v[i];
        }
        for(int i=1;i<=n;i++){
            vector<LL> dp(m+1);
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                for(int k=m;k>=w[j];k--){
                    dp[k] = max(dp[k] , dp[k-w[j]] + v[j]);
                }
            }
            LL ans = dp[m]-dp[m-w[i]] - v[i] + 1;
            if(ans<0) cout<<0<<endl;
            else cout<<ans<<endl;
        }
    }
    return 0;
}

 

E—清楚姐姐打怪升级

思路:若在一次时间间隔内的恢复量大于等于攻击力则杀不死

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=1e9;
typedef long long ll;
ll n,t,a,h,v,s=1;
int main(){
    cin>>n>>t>>a;
    bool ok=true;
    for(int i=0;i<n;++i){
        cin>>h>>v;
        h-=a,s+=t;
        if(h<=0)continue;
        if(t*v>=a){
            cout<<"-1";return 0;
        }
        else{
            s+=(h/(a-v*t))*t;
            if(h%(a-v*t))s+=t;
        }
    }
    cout<<s-t;
    return 0;
}

 

 L—清楚姐姐的三角形I

 思路:由公式求出三边,保证三条边为整数,再判断三边是否构成三角形

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=1e9;
int t;
typedef long long ll;
int main(){
    cin>>t;
    ll a,b,c,aa,bb,cc;
    while(t--){
        bool ok=true;
        cin>>a>>b>>c;
        if((a+c-b)%2||(b+c-a)%2||(a+b-c)%2)ok=false;
        else{
            bb=(a+c-b)/2;
            aa=(b+c-a)/2;
            cc=(a+b-c)/2;
        }
        if(!ok||((aa+bb)<=cc||(bb+cc)<=aa||(aa+cc)<=bb))cout<<"No\n";
        else {
            cout<<"Yes\n";
            cout<<aa<<' '<<bb<<' '<<cc<<'\n';
        }
    }
    return 0;
}

 


M—清楚姐姐的三角形II

思路:循环11212...
#include <iostream>
using namespace std;

int main() {
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        if((i+1)%3!=0){
            cout<<"1";
        }else{
            cout<<"2";
        }
        if(i!=n-1){
            cout<<" ";
        }
    }
}

 


 

Day 3

SMU Winter 2023 Round #9 (Div.2)

A-Who is The 19th ZUCCPC Champion

#include<bits/stdc++.h>
using namespace std;
const int N=3e4+5,M=1e5+5;
typedef long long ll;
int main(){
    cin.tie(0),cout.tie(0);
    cout<<"Ranni the Witch";
    return 0;
}

 

B-Jiubei and Overwatch

思路:找出最大的ai,判断与k*x的关系,求出最小ans

#include<bits/stdc++.h>
using namespace std;
const int N=3e4+5,M=1e5+5;
typedef long long ll;
int t,n,k,x,y,ma,m;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n>>k>>x>>y;
        ma=0;
        for(int i=0;i<n;++i){
            cin>>m;
            ma=max(ma,m);
        }
        int res=0;
        if(ma<=k*x){
            res+=(ma/x);
            if(ma%x)res++;
        }
        else{
            res+=k;
            ma-=(k*x);
            res+=(ma/y);
            if(ma%y)res++;
        }
        cout<<res<<'\n';
    }
    return 0;
}

 

C-Ah, It's Yesterday Once More

 思路:倒序输出n个数
#include<bits/stdc++.h>
using namespace std;
const int N=3e4+5,M=1e5+5;
typedef long long ll;
int t,n;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=n;i>=1;--i)cout<<i<<' ';
        cout<<'\n';
    }
    return 0;
}

 

F-Sum of Numerators

思路:k为0时,分子为1,2,3,...,n;k为1时,分子中偶数都除2,新的分子需减去1,2,...,n/2;依次减下去...直到k次或没有偶数(n为0)
 
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+5,M=1e5+5;
typedef long long ll;
ll t,n,k;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n>>k;
        ll s=(1+n)*n/2;
        for(int i=1;i<=k&&n!=0;++i){
            n/=2;
            s-=(1+n)*n/2;
        }
        cout<<s<<'\n';
    }
    return 0;
}

 

G-Guaba and Computational Geometry

思路:对x轴上的线段进行左端点排序,从左到右对于每个左端点,统计出右端点小于左端点的线段的最大w;同理求出y轴上的最大w;取最大w
 
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 5, mod = 1e9 + 7;
struct node{
    int x1, x2;
    int val;
    bool operator < (const node &k) const {
        return x1 < k.x1;
    }
}a[N];
struct P{
    int a, b, c, d;
    int val;
} b[N];
struct t{
    int b, val;
    bool operator < (const t &k) const{
        return b > k.b;
    }
};
priority_queue<t> q;
int get(int n)
{
    int ret = 0;
    int ma = -1;
    for (int i = 1; i <= n; i++)
    {
        while(!q.empty() && q.top().b < a[i].x1)
        {
            ma = max(ma, q.top().val);
            q.pop();
        }
        if (ma != -1) ret = max(ret, ma + a[i].val);
        q.push(t{a[i].x2, a[i].val});
    }

    while (!q.empty()) q.pop();

    return ret;
}
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld%lld%lld%lld", &b[i].a, &b[i].b, &b[i].c, &b[i].d);
    }
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &b[i].val);
    }


    for (int i = 1; i <= n; i++)
    {
        a[i].x1 = b[i].a, a[i].x2 = b[i].c;
        a[i].val = b[i].val;
    }
    sort(a + 1, a + 1 + n);
    int ans = 0;
    ans = max(ans, get(n));


    for (int i = 1; i <= n; i++)
    {
        a[i].x1 = b[i].b, a[i].x2 = b[i].d;
        a[i].val = b[i].val;
    }
    sort(a + 1, a + 1 + n);
    ans = max(ans, get(n));


    if (ans != 0) printf("%lld\n", ans);
    else puts("-1");
}
signed main()
{
    int tt = 1;
    cin >> tt;
    while (tt--) solve();
    return 0;
}

 

 I-Array Division

思路:求出ai与bi的差的前缀和,dp求出以1为左端,n为右端的区间段最大个数
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+5,M=1e5+5;
typedef long long ll;
ll t,n,a[N],b[N],d[N],p[N];
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        d[0]=p[0]=0;
        for(int i=1;i<=n;++i)cin>>a[i];
        for(int i=1;i<=n;++i)cin>>b[i],d[i]=a[i]-b[i],d[i]+=d[i-1];
        for(int i=1;i<=n;++i)p[i]=-1;
        for(int i=0;i<=n;++i){
            if(p[i]==-1)continue;
            for(int j=i+1;j<=n;++j)
                if(d[j]-d[i]>=0)p[j]=max(p[j],p[i]+1);
        }
        cout<<p[n]<<'\n';
    }
    return 0;
}

 

J-Substring Inversion (Easy Version)

思路:将所有子字符串排列,并记录左端点,从小到大标记每个子字符串的左端点,每次求出从该左端点往右中已标记过的子字符串个数
#include<bits/stdc++.h>
using namespace std;
const int N=410,M=1e9+7;
typedef long long ll;
ll t,n;
string s;
int a[N];
vector<pair<string,int> >ve;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        ve.clear();
        cin>>n>>s;
        string ss=s;
        for(int i=0;i<n;++i){
            a[i]=0;
            for(int j=i;j<n;++j){
                ve.push_back({ss.substr(i,j-i+1),i});
                ss=s;
            }
        }
        sort(ve.begin(),ve.end());
        ll res=0;
        for(int i=0;i<ve.size();++i){
            int j=ve[i].second;
            for(int k=j+1;k<n;++k)res+=a[k];
            a[j]++;
        }
        cout<<res%M<<'\n';
    }
    return 0;
}

 

 

L-Monster Tower

思路:用小顶堆维护k个数,若堆顶小于总量,则总量加堆顶,否则更新x,x=堆顶-总量,x取最大
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
ll t,n,k;
ll a[N];
priority_queue<ll,vector<int>,greater<int> >q;
ll sta,now;
int main() {
    cin >> t;
    while (t--) {
        cin >> n >> k;
        sta = 0;
        now = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
        }
        for (int i = 1; i <= n; i++) {
            if (q.empty() || q.size() < k) q.push(a[i]);//注意判空
            else {
                ll s = q.top();
                q.pop();
                if (now >= s)
                    now += s;
                else {
                    sta = max(sta, s - now);
                    now += s;
                    q.push(a[i]);
                }
            }
        }
        while (!q.empty()) {
            ll s = q.top();
            q.pop();
            if (now >= s)
                now += s;
            else {
                sta = max(sta, s - now);
                now += s;
            }
        }
        cout << sta << endl;

    }
    return 0;
}

 


 

 Day 5

2023牛客寒假算法基础集训营6

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=1e5+10;
const int mod=1e9+7;
int main()
{
    ll x;
    cin>>x;
    if(1<=x&&x<=7)cout<<"very easy";
    else if(7<x&&x<=233)cout<<"easy";
    else if(233<x&&x<=10032)cout<<"medium";
    else if(10032<x&&x<=114514)cout<<"hard";
    else if(114514<x&&x<=1919810)cout<<"very hard";
    else if(1919810<x)cout<<"can not imagine";
    return 0;
}

B-阿宁的倍数

思路:每次统计每个数的因数的个数,及每个数的倍数的前缀和,答案为倍数的总个数 - 该数前的倍数个数

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5, M = 1e9 + 7;

int n,q,f[N];
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n>>q;
    vector<int>a(n+1),p(n+1);
    for(int i=1;i<=n;++i){
        cin>>a[i];
        for(int j=1;j*j<=a[i];++j){
            if(a[i]%j==0){
                f[j]++;
                if(j*j!=a[i])f[a[i]/j]++;
            }
        }
        p[i]=f[a[i]];
    }
    int o,x;
    while(q--){
        cin>>o>>x;
        if(o==1){
            a.push_back(x);
            for(int i=1;i*i<=x;++i){
                if(x%i==0){
                    f[i]++;
                    if(i*i!=x)f[x/i]++;
                }
            }
            p.push_back(f[a.back()]);
        }
        else
            cout<<f[a[x]]-p[x]<<'\n';
    }
    return 0;
}

 

C-阿宁的大背包

思路:中间取最大,依次往两边减小
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3 + 5, M = 1e9 + 7;
ll n,a[N],b[N];
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n;
    ll x=(n+1)/2,y=x+1,s=n;
    while(x>0||y<=n){
        if(x>0)a[x--]=s--;
        if(y<=n)a[y++]=s--;
    }
    for(int i=1;i<=n;++i)b[i]=a[i];
    for(int i=n-1;i>=1;--i){
        for(int j=1;j<=i;++j){
            b[j]=(b[j]+b[j+1])%M;
        }
    }cout<<b[1]%M<<'\n';
    for(int i=1;i<=n;++i)cout<<a[i]<<' ';
    return 0;
}

 

D-阿宁的毒瘤题

思路:求u的前缀和、后缀和,求每个d前u个数的前缀和、每个d后u个数的后缀和;
枚举字符串,为d时,减少的数量为 前u个数 * 后u个数;为u时,减少的个数为 前每个d前u个数和 + 后每个d后的u个数和;
标记减少数量最大的位置即为答案
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5, M = 1e9 + 7;
string s;
ll l[N],r[N],dl[N],dr[N],ss,s1;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>s;
    for(int i=0;i<s.size();++i){
        if(s[i]=='u')ss++;
        l[i]=ss;
        if(s[i]=='d')s1+=l[i];
        dl[i]=s1;
    }
    ss=s1=0;
    for(int i=s.size()-1;i>=0;--i){
        if(s[i]=='u')ss++;
        r[i]=ss;
        if(s[i]=='d')s1+=r[i];
        dr[i]=s1;
    }
    ll ma=-1,t,a;
    for(int i=0;i<s.size();++i){
        a=0;
        if(s[i]=='d'){
            a=l[i]*r[i];
        }
        if(s[i]=='u'){
            a=dl[i]+dr[i];
        }
        if(a>ma){
            ma=a,t=i;
        }
    }
    s[t]='x';
    cout<<s;
    return 0;
}

 

 

  E-阿宁的生成树

思路:大于k+1的点到点1的边权都为1,剩余的一一枚举出最小的gcd(),每次为1时结束

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5, M = 1e9 + 7;

int n,k;
int main() {
    cin.tie(0), cout.tie(0);
    cin>>n>>k;
    ll s=min(n,k+1);
    ll ans=n-s;
    for(int i=2;i<=s;++i){
        ll a=i;
        for(int j=i+k+1;j<=n;++j){
            a=min(a,(ll)__gcd(i,j));
            if(a==1)break;
        }
        ans+=a;
    }
    cout<<ans;
    return 0;
}

 

 

 F-阿宁的二进制

思路:用大顶堆维护所有数,将所有不为1的数进行转换,记录每次转换后的堆顶
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5, M = 1e9 + 7;
int n,q,k,s[10*N];
priority_queue<int>qe;
int lowbit(int x){
    return x&(-x);
}
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n>>q;
    int a;
    for(int i=0;i<n;++i){
        cin>>a;
        if(a!=1)
        qe.push(a);
    }
    s[0]=0;
    while(!qe.empty()){
        int t=qe.top();qe.pop();
        if(t==1)break;
        int res=0;
        while(t)t-=lowbit(t),res++;
        qe.push(res);
        s[++s[0]]=qe.top();
    }
    while(q--){
        cin>>a;
        if(s[0]==0)cout<<1<<'\n';
        else if(a>s[0])cout<<s[s[0]]<<'\n';
        else cout<<s[a]<<'\n';
    }
    return 0;
}

 

G-阿宁的整数配对

思路:分别对正数、负数以绝对值进行排序,类归并排序选取对数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5, mod = 1e9 + 7;
int n,k,a[N],b[N];
bool cmp(int x,int y){
    return x>y;
}
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n>>k;
    int t;
    a[0]=b[0]=0;
    for(int i=1;i<=n;++i){
        cin>>t;
        if(t>=0)a[++a[0]]=t;
        else b[++b[0]]=t*(-1);
    }
    sort(a+1,a+a[0]+1,cmp),sort(b+1,b+b[0]+1,cmp);
    ll aa,bb,xx=0,yy=0;
    ll s=0;
    for(int i=1;i<=k;++i){
        aa=bb=0;
        if(a[0]>=2)aa=a[xx+1]*a[xx+2];
        if(b[0]>=2)bb=b[yy+1]*b[yy+2];
        if(a[0]<2&&b[0]<2){
            aa=a[xx+1]*b[yy+1];
            s-=aa;break;
        }
        if(aa>=bb){
            a[0]-=2;
            xx+=2;s+=aa;
        }
        else{
            b[0]-=2;
            yy+=2;s+=bb;
        }
    }
    cout<<s;
    return 0;
}

 

H-阿宁讨伐虚空

思路:在l~r中找出小于x的个数
 
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 5, mod = 1e9 + 7;
int main(){
    cin.tie(0),cout.tie(0);
    ll x,l,r,a,b;
    double s;
    cin>>x>>l>>r;
    if(x<l)s=0;
    else if(x>r)s=1;
    else{
        a=x-l,b=r-l+1;
        s=double(a)/double(b);
    }
    cout<<fixed<<setprecision(16)<<s;
    return 0;
}

 

I-阿宁前往沙城

思路:走过的路也可删,直接求1到n的最短路,若仅有一条路径,则只有第一条不可删掉,时间为该路权值,其余都为1;若多条路径,所有路都为1

 

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=2e5+3;
vector<pair<int ,int >>g[N];
int a[N];
void solve() {
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=m; i++) {
        int u,v,w;
        cin>>u>>v>>w;
        g[u].push_back({v,w}),g[v].push_back({u,w});
    }
    queue<int >q;
    a[1]=1;
    q.push(1);
    while(!q.empty()) {
        int x=q.front();
        q.pop();
        for(auto [i,j] :g[x]) {
            if(a[i]==0) a[i]=a[x]+1,q.push(i);
        }
    }
    if(a[n]-1!=m) cout<<a[n]-1;
    else cout<<a[n]-2+g[1][0].second;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

 

L-阿宁睡大觉



思路:总数为2n-1,一个噩梦所占数量:经过该点的次数 * 2(n -(x+y)+ 1),减去每行列数最小的噩梦(某些噩梦所占路线可能一样 )
 

 Day 6

第十届图灵杯NEUQ-ACM程序设计竞赛个人赛

A-有用的算法

思路:看序列是否有序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int n,a[N],b=0;
int main(){

    cin>>n;
    for(int i=0;i<n;++i){
        cin>>a[i];
    }
    for(int i=0;i<n;++i){
        if(i!=0&&(a[i]<a[i-1])){
            b=1;break;
        }
    }
    if(b==1){
        for(int i=0;i<n;++i){
            if(i!=0&&a[i]>a[i-1]){
                b=2;break;
            }
        }
    }
    if(b==0||b==1)cout<<"erfen is useful!";
    else cout<<"bukeyi";
    return 0;
}

B-平衡数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;

int main(){
    int t,n;
    cin>>t;
    while(t--){
        cin>>n;
        int a,b,c,d;
        a=n/1000;
        b=n/100-a*10;
        c=n/10-a*100-b*10;
        d=n%10;
        if((a+b)==(c+d))cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;
}

 

C-三角形

思路:求出边AC和边CB的线性方程,将点代入,判断是否超出范围

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;

int main(){
    double xb,xc,yc,k1,k2,b2,xp,yp,y1,y2;
    cin>>xb>>xc>>yc>>xp>>yp;
    k1=yc/xc,k2=yc/(xc-xb),b2=yc*xb/(xb-xc);
    y1=xp*k1,y2=k2*xp+b2;
    if(yp<y1&&yp<y2)cout<<"yes";
    else cout<<"no";
    return 0;
}

 

D-文稿修订

思路:只判断长度为4的单词
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e6+10,M=998244353;
char s[N];
int n,f[N];
int main(){
    cin.tie(0),cout.tie(0);
    s[0]=' ';
    int ans=0;
    while((s[++n]=::getchar())!='#'){}
    for(int i=1;i<n-3;++i){
        if((s[i-1]==' '||s[i-1]=='\n')&&(s[i+4]==' '||s[i+4]=='\n')&&(s[i]=='n'||s[i]=='N')){
            if((s[i+1]=='E'||s[i+1]=='e')&&(s[i+2]=='U'||s[i+2]=='u')&&(s[i+3]=='Q'||s[i+3]=='q')){
                ans++;
                if(s[i]=='N'&&s[i+1]=='E'&&s[i+2]=='U'&&s[i+3]=='Q')ans--,f[i]=1;
            }
        }
    }
    cout<<ans<<'\n';
    for(int i=1;i<n;++i){
        if(f[i]==1)cout<<"WOW N";
        else cout<<s[i];
    }
    return 0;
}

 

E-减肥计划

思路:n<=10,可用二进制枚举每一种情况;每种物品只有选和不选,可用dfs两种情况

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=15,M=998244353;
int n,a,b,c,x[N],y[N],z[N],w[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>a>>b>>c;
    for(int i=0;i<n;++i)cin>>x[i]>>y[i]>>z[i]>>w[i];
    int ans=0;
    for(int i=0;i<(1<<n);++i){
        int xx=0,yy=0,zz=0,ww=0;
        for(int j=0;j<n;++j){
            if(i>>j&1){
                xx+=x[j],yy+=y[j],zz+=z[j],ww+=w[j];
            }
        }
        if(xx<=a&&yy<=b&&zz<=c)ans=max(ans,ww);
    }
    cout<<ans;
    return 0;
}

 

 F-吃包子

思路:用前缀和求出范围内的肉包
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int n,m,s[N],p[N];
vector<int>a;
int main(){
    cin>>n>>m;
    int ss=0;
    for(int i=0;i<n;++i){
        cin>>s[i];
        if(s[i]==1)ss++;
        p[i]=ss;
        if(s[i]==0)a.push_back(p[i]);
    }
    int res=0;
    if(a.size()<=m)cout<<p[n-1];
    else{
        for(int i=0;i<a.size()-m+1;++i){
            if(i==0){
                res=max(res,a[i+m]);
            }
            else if(i+m-1==a.size()-1){
                res=max(res,ss-a[i-1]);
            }
            else{
                res=max(res,a[i+m]-a[i-1]);
            }
        }
        cout<<res;
    }
    return 0;
}

 

 G-数字鉴定

思路:暴力解
#include <bits/stdc++.h>

const int N = 1e6 + 7;
int n, q, l, r,i;
bool a[N];
bool is(int n)
{
    if (a[n])
        return false;
    else
    {
        for (i = 2 * n; i < N; i += n)
        {
            if (a[i])
                return false;
        }
        return true;
    }
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n >> q;
    while (n--)
    {
        std::cin >> l >> r;
        for (i = l; i <= r; i++)
            a[i] = true;
    }
    while (q--)
    {
        int x;
        std::cin >> x;
        std::cout << (is(x) ? "YES\n" : "NO\n");
    }
    return 0;
}

 

思路:p的值是循环的,求出其循环范围即可求出x
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e6+10;
LL n,p,k,b,t,x,a[N],vis[N],sum[N];
int main(){
    cin>>n>>p>>k>>b>>t;
    for(int i=0;i<n;i++)cin>>a[i];
    for(LL i=1;i<=t;i++){
        x+=a[p];
        if(vis[p]){
            LL len=i-vis[p];
            LL d=x-sum[p];
            LL tmp=(t-i)/len;
            LL r=(t-i)%len;
            x+=d*tmp;
            for(LL j=1;j<=r;j++)p=(k*p+b)%n,x+=a[p];
            break;
        }
        sum[p]=x;
        vis[p]=i;
        p=(p*k+b)%n;
        
    }
    cout<<x<<endl;
    return 0;
}

 


I-试题排版

思路:dp求完全背包方案数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10,M=998244353;
int n, m;
ll f[5100];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    f[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (j < i)
                continue;
            f[j] = (f[j] + f[j - i]) % M;
        }
    }
    cout << f[n] << "\n";
    return 0;
}

 

 J-QQ群

思路:环的入读大于等于1,求出非环的最长路径,加上环的长度
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e4 + 5, M = 1e9 + 7;

int n;
queue<int> q;
bool st[N];
int main() {
    cin.tie(0), cout.tie(0);
    cin>>n;
    vector<int> g[n+1],d(n+1),ru(n+1);
    int a;
    for(int i=1;i<=n;++i){
        cin>>a;
        g[i].push_back(a);
        ru[a]++;
    }
    for(int i=0;i<=n;++i){
        if(ru[i]==0){
            q.push(i);
            d[i]=1,st[i]=true;
        }
    }
    int ans=0;
    while(!q.empty()){
        int t=q.front();
        q.pop();
        for(auto x:g[t]){
            d[x]=max(d[x],d[t]+1);
            if(--ru[x]==0){
                q.push(x);
                st[x]=true;
            }
        }
    }
    for(int i=0;i<=n;++i)if(!st[i])ans++;
    int res=0;
    for(int i=0;i<=n;++i)res=max(res,d[i]);
    ans+=res;
    cout<<ans;
    return 0;
}

 

M-粉色头发的可爱女孩

思路:种类有20种,用二进制代表每种可能,更新包含某种可能的可能的最大值

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1<<22, M = 1e9 + 7;
int n,k,q;
pair<ll,ll> a[N];
int main() {
    cin.tie(0), cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;++i){
        ll aa,m,t=0,x;
        cin>>aa>>m;
        for(int j=1;j<=m;++j){
            cin>>x;
            t|=(1<<x-1);
        }
        if(aa>a[t].first){
            a[t].second=i,a[t].first=aa;
        }
    }
    for(int i=1<<k;i>=0;--i){
        for(int j=0;j<k;++j){
            int t=i|(1<<j);
            if(a[t].first>a[i].first){
                a[i].first=a[t].first,a[i].second=a[t].second;
            }
        }
    }
    cin>>q;
    while(q--){
        int m,t=0,x;
        cin>>m;
        while(m--){
            cin>>x;
            t|=(1<<x-1);
        }
        if(a[t].first)cout<<a[t].second<<'\n';
        else cout<<"OMG!\n";
    }
    return 0;
}

 

 
 
posted @ 2023-01-30 21:12  bible_w  阅读(13)  评论(0编辑  收藏  举报