week6

Day 1

蓝桥杯模拟赛 3

 

A-[蓝桥杯 2021 省 B2] 特殊年份

思路:直接比较每个数的个十百千位
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=2e5+5,INF=0x3f3f3f3f;
int s[5],ans;
int main(){
    int a,b,c,d;
    for(int i=0;i<5;++i){
        cin>>s[i];
        a=s[i]/1000,b=s[i]/100-a*10,c=s[i]/10-a*100-b*10,d=s[i]%10;
        if(a==c&&b+1==d)ans++;
    }
    cout<<ans;
    return 0;
}
View Code

 

 B-[蓝桥杯 2021 省 AB2] 小平方

思路:暴力枚举
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=2e5+5,INF=0x3f3f3f3f;
int n,ans;

int main(){
    cin>>n;
    int m=(n+1)/2;
    for(int i=1;i<n;++i){
        if(((i*i)%n)<m)ans++;
    }
    cout<<ans;
    return 0;
}
View Code

 

 

C-[蓝桥杯 2021 省 AB] 砝码称重

思路:每种砝码有三种取法:加上、不选、减去,dp[i][j]表示在前i个砝码中是否能选出总量为j的选法,dp[0][0]=true;
存在其中任意一种状态表示存在该种选法:1.不选:dp[i][j]=dp[i-1][j]  2.加上:dp[i][j]=dp[i-1][j-w[i]]  3.减去:dp[i][j]=dp[i-1][j+w[i]]
由于总量存在负数,所有总量加上迁移量N
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
int n,m,x,w[110];
bool f[110][N];
int main()
{
    cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>w[i];
        m+=w[i];
    }
    f[0][N/2]=true;
    for(int i=1;i<=n;++i){
        for(int j=-m;j<=m;++j){
            f[i][j+N/2]=f[i-1][j+N/2];
            if(j-w[i]>=-m)f[i][j+N/2]|=f[i-1][j-w[i]+N/2];
            if(j+w[i]<=m)f[i][j+N/2]|=f[i-1][j+w[i]+N/2];
        }
    }
    int res=0;
    for(int i=1;i<=m;++i)
        if(f[n][i+N/2])res++;
    cout<<res;
    return 0;
}
View Code

 

D-[蓝桥杯 2021 省 AB2] 完全平方数

思路:完全平方数的质因子成对出现,消去所有成对的质因子,剩余的质数即为答案
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=2e5+5,INF=0x3f3f3f3f;
ll n;

int main(){
    cin>>n;
    for(ll i=2;i*i<=n;++i){
        while(n%(i*i)==0){n/=(i*i);}
    }
    cout<<n;
    return 0;
}
View Code

 

 

E-[蓝桥杯 2021 省 B] 时间显示

思路:每天的时分秒数相同,算出有多少时分秒
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=2e5+5,INF=0x3f3f3f3f;
ll n;

int main(){
    cin>>n;
    ll h,m,s;
    n/=1000;
    h=n/3600%24;
    m=n/60%60;
    s=n%60;
    if(h<10)cout<<0;
    cout<<h<<':';
    if(m<10)cout<<0;
    cout<<m<<':';
    if(s<10)cout<<0;
    cout<<s;
    return 0;
}
View Code

 

 

F-[蓝桥杯 2021 省 B] 杨辉三角形

 思路:画个图斜着看,每斜的第一个数是第C(2k,k)个,大小递增;k最大为16,C(32,16)>=1e9;每斜二分找出满足C(s,k)大于等于n的最小的s,若C(s,k)等于n,即为该位置;答案为s*(1+s)/2+(k+1)
            1  ---> C(0, 0)
          1 
        1   2  ---> C(2, 1)
      1   3                             ---> C(2n, n)
    1   4   6  ---> C(4, 2)
  1   5   10
1   6   15  20 ---> C(6, 3)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=2e5+10;
int n;
ll C(int a,int b){
    ll res=1;
    for(int i=a,j=1;j<=b;++j,--i){
        res=res*i/j;
        if(res>n)return res;
    }
    return res;
}
bool check(int k){
    int l=2*k,r=max(n,l);
    while(l<r){
        int mid=l+r>>1;
        if(C(mid,k)>=n)r=mid;
        else l=mid+1;
    }
    if(C(r,k)!=n)return false;
    cout<<1ll*(r+1)*r/2+k+1;
    return true;
}

int main()
{
    cin.tie(0),cout.tie(0);
    cin>>n;

    for(int k=16;k>=0;--k){
        if(check(k))break;
    }
    return 0;
}
View Code

 

 

G-[蓝桥杯 2021 省 A] 左孩子右兄弟

 思路:答案为一点的最深子树的深度加上该点孩子数的最大值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2e5+5,INF=0x3f3f3f3f;
int n;
vector<int>g[N];
int dfs(int u){
    int s=g[u].size(),ans=0;
    for(int i=0;i<g[u].size();++i){
        ans=max(ans,dfs(g[u][i])+s);
    }
    return ans;
}
int main(){
    cin>>n;
    int x;
    for(int i=2;i<=n;++i){
        cin>>x;
        g[x].push_back(i);
    }
    int ans=dfs(1);
    cout<<ans;
    return 0;
}
View Code

 

H-[蓝桥杯 2021 省 AB2] 负载均衡

 思路:堆模拟,每台计算机正运算的任务按完成时间从小到大排序,同时记录消耗算力,每次比较该任务的开始时刻,将已完成的任务除去,并恢复算力
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+5;
int n,m,s[N];
priority_queue<PII,vector<PII>,greater<PII>> q[N];

int main()
{
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    int a,b,c,d;
    for(int i=1;i<=n;++i){
        cin>>s[i];
    }

    while(m--){
        cin>>a>>b>>c>>d;
        while(q[b].size()&&a>=q[b].top().first){
            s[b]+=q[b].top().second;
            q[b].pop();
        }
        if(d>s[b])cout<<"-1\n";
        else{
            q[b].push({c+a,d});
            s[b]-=d;
            cout<<s[b]<<'\n';
        }
    }
    return 0;
}
View Code

 

 

Day 3

SMU Winter 2023 Round #11 (Div.2)

 A-BCD

思路:向上整除

B-Poku's Vacation

思路:求满足1+2+...+x的和小于等于n的最大x

C-Dualites in Pain - The Beginning

思路:若第二大的数等于最大的数或差值为1则YES;或者像H题反向模拟
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+5,INF=1e9,M=1e3+10;
int n,a[105];
int main(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];
    sort(a,a+n);
    if(a[n-1]==a[n-2]||a[n-1]-1==a[n-2])cout<<"YES";
    else cout<<"NO";
    return 0;
}
View Code

D-Elder Ning

思路:每个怪都能杀才满足,枚举出最小左界和最大右界,界限成立则输出个数

E-Hostel Cleaning

思路:条件是个数少,接着是价格少,所有分为k类,每类累加求最小

F-No Internet IPC!

思路:每次连接好2n-1个,每次取min(限制,2n-1)进行累加,连接总数满足条件时的次数为答案

G-Dualites in Pain - The Conclusion

思路:每种课的次数x,存在的更新状态有x种:x、x-1、...、2、1,将所有更新状态存入单调队列,每种状态按位置的先后排序,按状态接着位置依次输出
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+5,INF=1e9,M=1e3+10;
int n,a[105];
int main(){
    vector<int>ve[1001];
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>a[i];
        int x=a[i];
        while(x){
            ve[x--].push_back(i);
        }
    }
    sort(a+1,a+n+1);
    if(a[n]==a[n-1]||a[n]-1==a[n-1]){
        for(int i=1000;i>=1;--i){
            for(auto w:ve[i])
                cout<<w<<' ';
        }
    }
    else cout<<-1;
    return 0;
}
View Code

H-Perfect Array

思路:反向模拟出答案,倒叙枚举,若当前q-th等于q则取出作为最后一步的数字 
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+5,INF=1e9,M=1e3+10;
int n;
vector<int> ve,ans;
int main(){
    cin>>n;
    int x;
    for(int i=0;i<n;++i){
        cin>>x;
        ve.push_back(x);
    }
    vector<int>c;
    while(ans.size()!=n){
        c.clear();
        bool ok=false;
        for(int i=ve.size()-1;i>=0;--i){
            if(!ok&&ve[i]==i+1){
                ans.insert(ans.begin(),ve[i]);ok=true;
                continue;
            }
            c.insert(c.begin(),ve[i]);
        }
        if(c.size()==ve.size()){
            cout<<"NO";
            return 0;
        }
        ve.clear();
        ve=c;
    }
    cout<<"YES\n";
    for(auto t:ans)cout<<t<<' ';
    return 0;
}
View Code

 

 

Day 5

SMU Winter 2023 Round #12 (Div.2)

A - KK 画猪

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;

int main(){
    cin.tie(0),cout.tie(0);
    string a;
    cin>>a;
    cout<<"  (\\____/)\n"
          "  / @__@ \\\n"
          " (  (oo)  )\n"
          "  `-.~~.-'\n"
          "   /    \\\n"
          " @/      \\_\n"
          "(/ /    \\ \\)\n"
          " WW`----'WW";
    return 0;
}
View Code

 

B - KK 学几何

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;
int n,t,r,l,h,w;
double s;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n;
    while(n--){
        cin>>t;
        if(t==1){
            cin>>r;
            s=s+double(3*r*r);
        }
        else if(t==2){
            cin>>l>>h;
            s=s+double(l*h)/2;
        }
        else if(t==3){
            cin>>l>>w;
            s=s+double(l*w);
        }
    }
    cout << fixed << setprecision(1)<<s;
    return 0;
}
View Code

 

 C - KK 算日期

思路:不算0元年,n+m小于0时绝对值加一

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;
int t,n,m;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n>>m;
        n+=m;
        if(n<=0){
            n=abs(n);
            n++;
        }
        if(n%4==0&&n%100!=0||n%400==0)cout<<29<<'\n';
        else cout<<28<<'\n';
    }
    return 0;
}
View Code

 

D - KK 与卡牌

思路:将武力值转化为整数,kk的所有卡牌按武力值大小分别存储名字,每种武力值的名字按字典序排序,用前缀和求出大于该武力值的卡牌个数,当物理值相等时,二分求出字典序小于该名字的卡牌,求出其个数

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;
int n,t,r,l,h,w;
double s;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n;
    while(n--){
        cin>>t;
        if(t==1){
            cin>>r;
            s=s+double(3*r*r);
        }
        else if(t==2){
            cin>>l>>h;
            s=s+double(l*h)/2;
        }
        else if(t==3){
            cin>>l>>w;
            s=s+double(l*w);
        }
    }
    cout << fixed << setprecision(1)<<s;
    return 0;
}
View Code

 

E - KK 与答辩

思路:每个人参加的场数等于分数小于kk的场数即满足条件

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;
int t,n,a,cnt[105];
map<string,int>ma,mb;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        int res=0;
        ma.clear();
        mb.clear();
        cin>>n;
        while(n--){
            cin>>a;
            string ss[10];
            int b,c,kk;
            for(int i=0;i<a;++i){
                cin>>ss[i]>>b>>c;
                mb[ss[i]]++;
                if(i==0)kk=b+c;
                if(i!=0&&b+c<kk)ma[ss[i]]++;
            }
        }
        for(auto t:mb){
            if(ma[t.first]==t.second)res++;
        }
        cout<<res<<'\n';
    }
    return 0;
}
View Code

 

F-KK 与刷题

思路:更新到ai为止每个数出现的个数,算出[1,ai-1]区间的数的个数和,用线段树计算;

线段树

 

这是个结构体数组。

数字是数组下标,[ i,j]表示i~j区间的数据和;

添加一个数a,从1节点开始向下,直到[l,r]的l=r=a;

查找一个数a,求[1,a-1]从1节点开始向下,有三种情况:[1,a-1]在左孩子范围之内、[1,a-1]在右孩子范围之内、两边都包含

 

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+1,INF=1e9,M=1e5+10;
struct sc{
    int l=1,r=0;
    int v=0;
}s[3*N];
void init(){
    s[1].l=1,s[1].r=100000;
    queue<int> q;
    q.push(1);
    while(s[q.front()].l!=s[q.front()].r){
        int size=q.size();
        for(int i=0;i<size;++i){
            int mid=(s[q.front()].l+s[q.front()].r)>>1;
            s[q.front()*2].l=s[q.front()].l,s[q.front()*2].r=mid;
            s[q.front()*2+1].l=mid+1,s[q.front()*2+1].r=s[q.front()].r;
            q.push(q.front()*2);
            q.push(q.front()*2+1);
            q.pop();
        }
    }
}
int solve(int h,int v1,int v2){
    int l=s[h].l,r=s[h].r,mid=l+r>>1,sum=0;
    if(v1<=l&&v2>=r)sum+=s[h].v;
    else if(mid>=v2)sum= solve(2*h,v1,v2);
    else if(mid<v1)sum= solve(2*h+1,v1,v2);
    else
        sum= solve(2*h,v1,mid)+ solve(2*h+1,mid+1,v2);
    return sum;
}
int main(){
    cin.tie(0),cout.tie(0);
    int n,a,ans=0,ma=0;
    cin>>n;
    init();
    for(int i=0;i<n;++i){
        cin>>a;
        ll ll=1;
        while(s[ll].l!=s[ll].r){
            int mid=s[ll].l+s[ll].r>>1;
            s[ll].v++;
            if(a<=mid)ll*=2;
            else ll=ll*2+1;
        }
        s[ll].v++;
        int same=s[ll].v;
        int less=solve(1,1,a-1);
        int more=i+1-same-less;
        int t=less-more;
        ans+=t;
        ma=max(ma,ans);
    }
    cout<<ma<<' '<<ans;
    return 0;
}
View Code

 

G - KK 看跳舞

思路:将所有序列看作倒序,则将除了1到n外,将存在正序的序列倒转,再将n前的数插进末尾后判断序列是否倒序即可

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;

int t,n;
vector<int>a;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        a.clear();
        a.push_back(0);
        cin>>n;
        int x,sn;
        for(int i=1;i<=n;++i){
            cin>>x;
            a.push_back(x);
            if(x==n)sn=i;
        }
        if(a[1]+1==a[2]||a[2]+1==a[3]){
            reverse(a.begin()+1, a.end());
            sn=n-sn+1;
        }
        vector<int>b;
        b.push_back(0);
        for(int i=sn;i<=n;++i)b.push_back(a[i]);
        for(int i=1;i<sn;++i)b.push_back(a[i]);
        bool ok=true;
        for(int i=1;i<=n;++i){
            if(b[i]!=b[i+1]+1&&i+1<=n){
                ok=false;break;
            }
        }
        if(ok)cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;
}
View Code

 

H - KK 与十佳

思路:存在负数的情况下,若无正数,负数个数为奇则输出最大负数,负数个数为偶则输出最小负数;若有正数,负数个数为偶则输出最小正数,负数个数为奇数则输出最大负数

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e4+5,INF=1e9,M=1e3+10;
int n,fm=-INF,fmi,fc,zx=INF,zc;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n;
    int x;
    for(int i=0;i<n;++i){
        cin>>x;
        if(x<0){
            fm=max(fm,x);
            fmi=min(fmi,x);
            fc++;
        }
        else{
            zx=min(zx,x);
            zc++;
        }
    }
    if(zc==0){
        if(fc%2==0)cout<<fmi;
        else cout<<fm;
        return 0;
    }
    if(fc==0){
        cout<<zx;
        return 0;
    }
    if(fc%2==0)cout<<zx;
    else cout<<fm;
    return 0;
}
View Code

 

I - KK 买股票

思路:记录下前i个数中最小的数,枚举第i个数与前i-1的数中最小值的差,求最大

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+5,INF=1e9,M=1e3+10;
int n,a[N],s[N];
int main(){
    cin.tie(0),cout.tie(0);
    cin>>n;
    s[0]=INF;
    int res=0;
    for(int i=1;i<=n;++i){
        cin>>a[i];
        s[i]=min(s[i-1],a[i]);
        if(i>1){
            res=max(res,a[i]-s[i-1]);
        }
    }
    cout<<res;
    return 0;
}
View Code

 

J - KK与英语

思路:将is变为was,且前后有空格

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+5,INF=1e9,M=1e3+10;
string s;
int main(){
    cin.tie(0),cout.tie(0);
    getline(cin,s);
    for(int i=1;i<s.size()-2;++i){
        if(s[i]=='i'&&s[i+1]=='s'&&s[i-1]==' '&&s[i+2]==' ')
            s.replace(i,2,"was");
    }
    cout<<s;
    return 0;
}
View Code

 

K-KK 与线代

思路:求出行列式等式-2028-442*x

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e3+5,INF=1e9,M=1e3+10;
int l,r;
int main(){
    cin.tie(0),cout.tie(0);
    cin>>l>>r;
    ll s;
    s=max(r,l);
    ll res=-2028-442*s;
    cout<<res;
    return 0;
}
View Code

 

 L-KK 学五子棋

思路:
对于每个0的位置,若满足下2后连成5个2则Win,若满足下2后刚好阻止5个1一条线且只存在一个2满足则Defense,存在多个则Defeated,若不能使2赢,也不能让1赢,则Defense
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e3+5,INF=1e9,M=1e5+10;
int t,n,m;
int d[N][N];
int a[N][N];
bool st[N][N];
int dx[8]= {-1,-1,0,1,1,1,0,-1};
int dy[8]= {0,1,1,1,0,-1,-1,-1};
int f(int u,int x,int y){
    int ans=0;
    int xx,yy;
    for(int i=0;i<4;++i){
        int res=0;
        xx=x+dx[i],yy=y+dy[i];
        while(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]==u){
            res++;
            xx+=dx[i],yy+=dy[i];
        }
        xx=x+dx[i+4],yy=y+dy[i+4];
        while(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]==u){
            res++;
            xx+=dx[i+4],yy+=dy[i+4];
        }
        ans=max(ans,res);
        if(ans>=4)break;
    }
    return ans;
}
int main(){
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n>>m;
        memset(st,false,sizeof st);
        int xx,yy;
        bool ok3=true;
        for(int i=0;i<n;++i)
            for(int j=0;j<m;++j)
                cin>>a[i][j];
        memset(d,0,sizeof d);
        bool ok1=true,ok2=true;
        int x1,y1,x2,y2,cn2=0;
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                if(a[i][j]==0){
                    if(ok3){
                        xx=i,yy=j;ok3=false;
                    }
                    if(f(2,i,j)>=4){
                        x1=i,y1=j;
                        ok1=false;break;
                    }
                    if(f(1,i,j)>=4){
                        x2=i,y2=j;cn2++;
                        ok2=false;
                    }
                }
            }
            if(!ok1)break;
        }
        if(!ok1){
            cout<<"Win\n"<<x1+1<<' '<<y1+1<<'\n';
        }
        else if(!ok2){
            if(cn2==1)
                cout<<"Defense\n"<<x2+1<<' '<<y2+1<<'\n';
            else cout<<"Defeated\n";
        }
        else{
            cout<<"Defense\n"<<xx+1<<' '<<yy+1<<'\n';
        }
    }
    return 0;
}
View Code

 

M-KK 与二叉树

posted @ 2023-02-06 19:39  bible_w  阅读(14)  评论(0编辑  收藏  举报