Problem A Good 的集合

https://ac.nowcoder.com/acm/contest/911/A

题意:输出最大的 good 的点集大小。

题解:枚举

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,l,r,u,v;
int ans,cnt,flag,temp,sum;
pair<int,int> a[9]={pair<int,int>(0,0),pair<int,int>(0,1),pair<int,int>(0,2),
                    pair<int,int>(1,0),pair<int,int>(1,1),pair<int,int>(1,2),
                    pair<int,int>(2,0),pair<int,int>(2,1),pair<int,int>(2,2)};
map<pair<int,int>,int>mp;
int check(int x){
    for(int i=0;i<9;i++){
        if((x>>i)&1)
        for(int j=i+1;j<9;j++){
            if((x>>j)&1)
            for(int c=j+1;c<9;c++){
                if((x>>c)&1){
                    if((a[i].first+a[j].first+a[c].first)%3==0&&(a[i].second+a[j].second+a[c].second)%3==0)return 0;
                }
            }
        }
    }
    return 1;
}
void dfs(int x,int y,int z){
    if(z==9)return;
    if(check(x|(1<<z))&&mp[a[z]]){
        int cnt=min(mp[a[z]],2);
        ans=max(ans,y+cnt);
        dfs(x|(1<<z),y+cnt,z+1);
    }
    dfs(x,y,z+1);
}
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    for(int i=0;i<9;i++){
        mp[a[i]]=0;
    }
    cin>>n;
    int x,y;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        mp[pair<int,int>(x%3,y%3)]++;
    }
    dfs(0,0,0);
    cout<<ans<<endl;
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem B 狂赌之渊

https://ac.nowcoder.com/acm/contest/911/B

题意:

题解:博弈论

C++版本一

题解:当和为奇数时为n,否则为0

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v;
int ans,cnt,flag,temp,sum;
int a[N];
char str;
struct node{};
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    cout<<(sum&1?n:0)<<endl;
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem C 随机独立集

 

题意:

题解:

C++版本一

 

Problem D O(n!)

https://ac.nowcoder.com/acm/contest/911/D

题意:有 n件商品,第 i件商品价格为 a[i],购买后,其它所有未购买的商品价格乘上 p[i],现在要买下所有商品,输出最小耗费。

题解:排序+贪心

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v;
double ans,cnt,flag,temp,sum;
char str;
struct node{
    int a;
    double p;
    bool operator<(const node &S)const{
        return S.a+a*S.p>S.a*p+a;
    }
}e[N];
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%lf",&e[i].a,&e[i].p);
    sort(e+1,e+n+1);
    double P=1.0;
    for(int i=1;i<=n;i++){
        ans+=e[i].a*P;
        P*=e[i].p;
    }
    printf("%f\n",ans);
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem E 斐波那契串

https://ac.nowcoder.com/acm/contest/911/E

题意:输出F[x]的第 y 位

题解:贪心+模拟+数学

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
ll t,n,m,k,p,l,r,u,v;
ll ans,cnt,flag,temp,sum;
ll f[1000];
string str1,str2;
struct node{};
char sloved(ll x,ll y){//out<<x<<y<<endl;
    if(x==1)
        return str1[y-1];
    if(x==2)
        return str2[y-1];
    return y<=f[x-1]?sloved(x-1,y):sloved(x-2,y-f[x-1]);
}
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    cin>>str1>>str2;
    f[1]=str1.size();
    f[2]=str2.size();
    cnt=100;
    for(int i=3;i<=100;i++){
        f[i]=f[i-1]+f[i-2];//cout<<f[i]<<endl;
        if(f[i]>=1e18){cnt=i;break;}
    }
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&p,&k);
        cout<<sloved(min(p,cnt),k)<<endl;
    }
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem F 无交集的圆

https://ac.nowcoder.com/acm/contest/911/F

题意:Y轴上有许多圆,所有圆的圆心位于Y轴,求有多少对圆是没有交集的(不包含、不相交、不相切)。

题解:二分

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v;
ll ans,cnt,flag,temp,sum;
int a[N],b[N];
char str;
struct node{
    double p,r;
}e[N];
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&e[i].p,&e[i].r),a[i]=e[i].p-e[i].r,b[i]=e[i].p+e[i].r;
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++){
        ans+=(lower_bound(b+1,b+n+1,e[i].p-e[i].r)-b)+n-(upper_bound(a+1,a+n+1,e[i].p+e[i].r)-a);
        //cout<<ans<<endl;
    }
    cout<<ans/2<<endl;
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem G 最长递增长度

https://ac.nowcoder.com/acm/contest/911/G

题意:最长严格递增子序列的长度

题解:最长的严格递增子序列

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v;
int ans,cnt,flag,temp,sum;
int a[N];
char str;
struct node{};
int dp[N];
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d",&n);
    memset(dp,0x3f,sizeof(dp));
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),*lower_bound(dp+1,dp+n+1,a[i])=a[i];
    printf("%lld\n",lower_bound(dp+1,dp+n+1,INF)-(dp+1));
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem H 虚无的后缀

https://ac.nowcoder.com/acm/contest/911/H

题意:给出 n 个数字,第 i 个数字为 a[i],我们从中选出 k 个数字,使得乘积后缀 0 的个数最多。

题解:DP+01背包

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=5000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v;
int ans,cnt,flag,temp,sum;
ll a[N];
int dp[200+10][N];
char str;
struct node{
    int cnt5,cnt2;
}e[N];
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d%d",&n,&m);
    memset(dp,-1,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        while(a[i]%2==0){
            a[i]/=2;
            e[i].cnt2++;
        }
        while(a[i]%5==0){
            a[i]/=5;
            e[i].cnt5++;
        }
        for(int j=m;j>=1;j--){
            for(int k=26*200;k>=e[i].cnt5;k--){
                if(dp[j-1][k-e[i].cnt5]!=-1){
                    dp[j][k]=max(dp[j][k],dp[j-1][k-e[i].cnt5]+e[i].cnt2);
                    ans=max(ans,min(dp[m][k],k));//cout<<j<<" "<<k<<" "<<ans<<" "<<dp[j][k]<<endl;
                }
            }
        }
    }
    cout<<ans<<endl;
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem I 大吉大利

https://ac.nowcoder.com/acm/contest/911/I

题意:需要弃置的最少金币

题解:二分

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v;
int ans,cnt,flag,temp,sum;
int a[N],b[N];
char str;
struct node{};
bool check(int mid){
    int c=a[1]-mid;
    cnt=0;
    for(int i=2;i<=n;i++){
        if(a[i]>c){//cout<<cnt<<endl;
            cnt+=ceil((a[i]-c)/(1.0*b[i]));
        }
    }
    return cnt<=mid;
}
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=2;i<=n;i++)scanf("%d",&b[i]);
    ans=-1;
    l=0;
    r=a[1];
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)){
            ans=mid;
            r=mid-1;
        }else{
            l=mid+1;
        }
    }
    cout<<ans<<endl;
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem J 异或的路径

https://ac.nowcoder.com/acm/contest/911/J

题意:给一棵 n 个点的树,1 号节点为根,边有边权,令 f(u,v) 表示 u 节点到 v 节点,路径上边权异或值。求 结果对 1000000007 取模。

题解:DFS+位运算

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v,w;
ll ans,cnt,flag,temp,sum;
ll dis[N];
int vis[N];
int cct[N];
char str;
struct node{
    int u,v,w;
    node (){};
    node(int u,int v,int w):u(u),v(v),w(w){}
};
vector<node>G[N];
void dfs(int u,int now){
    dis[u]=now;
    vis[u]=1;
    int z=now;
    int cnt=0;
    while(z){
        if(z&1)cct[cnt]++;
        cnt++;
        z>>=1;
    }
    for(int i=0,j=G[u].size();i<j;i++){
        int v=G[u][i].v;
        if(!vis[v]){
            dfs(v,now^G[u][i].w);
        }
    }
}
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    //scanf("%d",&t);
    //while(t--){
    scanf("%d",&n);
    for(int i=2;i<=n;i++){
        scanf("%d%d",&p,&v);
        G[p].push_back({p,i,v});
        G[i].push_back({i,p,v});
    }
    dfs(1,0);
    for(int i=1;i<=n;i++){
        for(int j=0;j<60;j++){
            if((dis[i]>>j)&1)ans+=1ll*(1ll<<j)%MOD*(n-cct[j]);
            else ans+=1ll*(1ll<<j)%MOD*cct[j];
            ans%=MOD;
        }
    }
    cout<<ans<<endl;
    //}

#ifdef DEBUG
	printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
    //cout << "Hello world!" << endl;
    return 0;
}

Problem K 宝石序列

 

题意:

题解:

C++版本一

 

Problem L 最优子区间

 

题意:

题解:

C++版本一