2017年百度之星部分题解

初赛A

小C的倍数问题 p-1因子个数

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
int main()
{
    int T;
    cin >> T;
    while (T--){
        long long x;
        cin >> x;
        long long ans = 0;
        for (long long  i = 1LL; i*i<x;i++){
            if ((x-1) % i == 0) ans+=2;
            if (i*i == x-1) ans--;
        }
        cout << ans <<endl;
    }
    return 0;
}
View Code

今夕何夕 模拟

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
string s[105];
int main()
{
    int T;
    cin >> T;
    while (T--){
        int y,m,d,c,g=0;
        int x = 0;
        scanf("%d-%d-%d",&y,&m,&d);

        if (m==1||m==2){
            m += 12;
            y--;
            g = 1;
        }
        int ty = y;
        c = (y)/100;
        y=y-100*c;
        x = ((y+y/4+c/4-2*c+26*(m+1)/10 + d - 1 + 7) % 7 + 7 ) % 7;
        int flag = 0;
        if ((((ty+1)%4==0&&(ty+1)%100!=0)||(ty+1)%400==0)&&(m==14&&d==29)) flag = 4;
        else flag = 1;
        int tx = 0;
        for (int i = ty+flag; i<=9999;i+=flag){
                c = (i)/100;
                y=i-100*c;
                if ((flag == 4)&&!((((i+1)%4==0&&(i+1)%100!=0)||(i+1)%400==0))) continue;
                tx = ((y+y/4+c/4-2*c+26*(m+1)/10 + d - 1 + 7) % 7 + 7 ) % 7;
                if (tx == x){
                    cout<<i+g<<endl;
                    break;
                }
        }
    }
    return 0;
}
View Code

度度熊的01世界 暴力dfs

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
string s;
int pic[110][110];
int vis[110][110];
int cnt[3];
int tx[4] = {0,0,1,-1};
int ty[4] = {1,-1,0,0};
int n,m;
void dfs(int x,int y,int t){

    if (x<0||y<0||x>n+1||y>m+1) return;
    if (pic[x][y]!=t) return;
    if (vis[x][y]) return;
    vis[x][y] = 1;
    for (int i = 0; i<4; i++)
        dfs(x+tx[i],y+ty[i],t);
    return;
}
int main()
{
    while (cin >> n >>m){

        memset(vis,0,sizeof(vis));

        for (int i = 0; i<=m+1;i++)
            pic[0][i] = pic[n+1][i] = 0;
        for (int i = 1; i<=n;i++){
            cin >> s;
            pic[i][0] = pic[i][m+1] = 0;
            for (int j = 1; j<=m;j++)
                pic[i][j] = s[j-1] - '0';
        }
        cnt[1] = cnt[0] = 0;
        for (int i = 0;i<=n+1; i++){
            for (int j = 0; j<=m+1; j++){
                if(vis[i][j] == 0 ){
                    dfs(i,j,pic[i][j]);
                    cnt[pic[i][j]]++;
                }
            }
        }
        if (cnt[1] == 1 && cnt[0] == 1) puts("1");
        else if (cnt[1] == 1 &&cnt[0] == 2) puts("0");
        else puts("-1");
    }
    return 0;
}
View Code

初赛B

Chess 简单组合数

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;\
const long long N = 1000 + 5;
const long long MOD = (long long)1e9 + 7;
long long F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
    inv[1] = 1;
    for(long long i = 2; i < N; i ++){
        inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
    }
    F[0] = Finv[0] = 1;
    for(long long i = 1; i < N; i ++){
        F[i] = F[i-1] * 1ll * i % MOD;
        Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
    }
}
long long C(int n, int m){
     if(m < 0 || m > n) return 0;
     return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
int main()
{
    int T;
    cin >> T;
    init();
    while (T--){
        int N,M;
        cin >> N >> M;
        cout << C(max(N,M),min(N,M))<<endl;
    }
}
View Code

度度熊的交易计划 最小费用可行流

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
struct edge{
   int from,to,cap,cost,next;
}E[160000];
int tot;
int head[600];int dis[600];
int inq[600];
int pre[600];
int maxf = 0;
int n,m;
void addedge(int a,int b,int cap, int cost)
{
    E[tot].from = a;
    E[tot].to = b;
    E[tot].cap = cap;
    E[tot].cost = cost;
    E[tot].next = head[a];
    head[a] = tot++;
    //反向边
    E[tot].from = b;
    E[tot].to = a;
    E[tot].cap = 0;
    E[tot].cost = -cost;
    E[tot].next = head[b];
    head[b] = tot++;
}
void init(){
    for (int i = 1; i<=n;i++){
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        addedge(n+1,i,b,a);
        addedge(i,n+2,d,-c);
    }
    for (int i = 1; i<=m;i++){
        int u,v,k;
        scanf("%d%d%d",&u,&v,&k);
        if (u==v) continue;
        addedge(u,v,INF,k);
        addedge(v,u,INF,k);
    }

}
void initfirst()
{
    memset(E,0,sizeof(E));
    memset(head,-1,sizeof(head));
    memset(pre,-1,sizeof(pre));
    tot = 0;
    maxf = 0;
}bool spfa(int b , int e)
{
    memset(dis,INF,sizeof(dis));
    memset(inq,false,sizeof(inq));
    memset(pre, -1, sizeof(pre));
    queue<int> q;
    dis[b] = 0;
    inq[b] = true;
    q.push(b);
    while (!q.empty())
    {
        int u = q.front() ;q.pop();
        for (int i = head[u]; i!=-1 ; i = E[i].next)
        {
            int v = E[i].to;
            if (E[i].cap && dis[v] > dis[u] + E[i].cost)
            {
                dis[v] = dis[u] + E[i].cost;
                pre[v] = i;
                if (!inq[v])
                    {q.push(v);inq[v] = true;}
            }
        }
        inq[u] = false;
    }
    if (dis[e]>=0) return false;
    else return pre[e]!=-1;
}
int MCMF(int b ,int e)
{
    int ANS = 0;
    while (spfa(b,e))
    {

        int minf = INF;
        for (int i = e ; i!=b ; i = E[pre[i]].from)
        {
            minf = min(minf , E[pre[i]].cap);
        }
        for (int i = e ; i!=b ; i = E[pre[i]].from)
        {
            E[pre[i]].cap -= minf;
            E[pre[i]^1].cap += minf;
        }
        maxf += minf;
        ANS += (minf*dis[e]);
    }
    return ANS;
}
int main()
{
        while (cin >> n >> m){
            initfirst();
            init();
            int ans = MCMF(n+1,n+2);
            cout << -ans << endl;
        }

}
View Code

小小粉丝度度熊 傻逼双指针,傻逼数据有负数,艹TMGBD。

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
struct node{
    int l,r;
}E[100011],G[100011];
int N;
int M;
bool cmp(node a,node b){
    if (a.l == b.l) return a.r < b.r;
    else return a.l < b.l;
}
int main()
{
    while (scanf("%d%d",&N,&M)==2){
        memset(E,0,sizeof(E));
        memset(G,0,sizeof(G));
        for (int i = 1; i<=N; i++)
            scanf("%d%d",&E[i].l,&E[i].r);


        sort(E+1,E+N+1,cmp);
        int nowL=E[1].l,nowR=E[1].r;
        int cnt=0;
        for(int i=2;i<=N;i++) {
        if(nowR<E[i].l) {
            G[++cnt]=node{nowL,nowR};
            nowL=E[i].l;
            nowR=E[i].r;
        }
        else if(nowR<E[i].r) nowR=E[i].r;
        }
        G[++cnt]=node{nowL,nowR};
        /*
        int cnt = 0;
        G[0].r = G[0].l = -1;
        for (int i = 1; i<=N; i++){
            if (E[i].l <= G[cnt].r+1) G[cnt].r = max(E[i].r,G[cnt].r);
            else G[++cnt] = E[i];
        }*/
        int cost = 0;
        int L=1,R=1;
        int  ans  = 0;
        for (int i = 1; i<=N; i++)
        {
            while(R+1<=cnt&&cost+G[R+1].l-G[R].r-1<=M) {
                cost+=G[R+1].l-G[R].r-1;
                R++;
            }
            ans=max(ans,G[R].r-G[L].l+1+M-cost);
            cost-=G[L+1].l-G[L].r-1;
            L++;
        }
        /*int ans = G[1].r - G[1].l+1;
        int sum = ans + M;
        for (int i = 2; i<=cnt; i++){
            ans += (G[i].r - G[i-1].r);
            cost += (G[i].l - G[i-1].r - 1);
            while (cost > M){
                ans -= (G[L+1].l - G[L].l);
                cost -= (G[L+1].l - G[L].r - 1);
                L++;
            }
            sum = max(sum,ans+M-cost);
        }
        */
        cout << ans <<endl;
    }
    return 0;
}
View Code

路径计数 计数+NTT

#include <bits/stdc++.h>
const long long MOD = 998244353;
const double ex = 1e-10;
typedef long long LL;
#define inf 0x3f3f3f3f
using namespace std;
const int N = 16064;
const int p = 998244353;
const int G = 3;
const int NUM = 25;
LL x1[N],x2[N],wn[NUM];
LL F[N],Finv[N],inv[N];
inline LL quick_mod(LL a,LL b,LL m){
    LL ans = 1;
    a %= m;
    while (b){
        if (b % 2 == 1)ans =  ans * a % m;
        b/=2;
        a = a * a % m;
    }
    return ans;
}
inline void GetWn(){
    for (int i = 0 ; i <NUM ; i++){
        int t = 1 << i;
        wn[i] = quick_mod(G,(p-1)/t,p);
    }
}
inline void Rader(LL a[],int len){
    int j = len >> 1;
    for (int i = 1 ; i< len- 1; i++){
        if (i <j) swap(a[i],a[j]);
        int k =  len >> 1;
        while( j >= k){
            j-=k;k>>=1;
        }
        if ( j < k ) j+=k;
    }
}
inline void NTT(LL a[],int len,int on){
    Rader(a,len);
    int id = 0;
    for (int h = 2; h <=len ; h <<=1){
        id ++;
        for (int j = 0 ; j< len ; j+=h){
            LL w = 1;
            for (int k = j ; k < j + h/2 ; k++){
                LL u = a[k] % p;
                LL t = w * ( ( a[k+h/2] ) % p ) % p; // 注意a的下标
                a[k] = (u+t) %p;
                a[k + h / 2] = (((u-t) % p) + p) % p;
                w = w * wn[id] % p;
            }
        }
    }
    if (on == -1){
        for (int i = 1; i<len/2 ; i++){
            swap(a[i],a[len-i]);
        }
        LL Inv = quick_mod(len,p-2,p);
        for (int i = 0; i<len; i++){
            a[i] = a[i] % p * Inv % p;
        }
    }
}
inline void  conv(LL a[],LL b[],int n){
    NTT(a,n,1);
    NTT(b,n,1);
    for (int i = 0 ; i < n; i++)
        a[i] = a[i] * b[i] % p;
    NTT(a,n,-1);
}
inline void init(){
    inv[1] = 1;
    for (int i = 2; i<N; i++){
        inv[i] = (MOD-MOD/i) *1ll *inv[MOD % i] % MOD;
    }
    F[0] = Finv[0] = 1;
    for (int i = 1 ;i<N; i++){
        F[i] = F[i-1] * i % MOD;
        Finv[i] = Finv[i-1] *1ll*inv[i] % MOD;
    }
    return;
}
LL A[5][16064];
inline void getA(int d,int id){
    for (int i = 1 ; i <= d ; i++){
        A[id][i] = F[d-1]*Finv[i-1]%MOD * Finv[d-i]  % MOD * Finv[i] % MOD;
    }
}
int main()
{
    init();
    GetWn();
    int aa[5];
    while (cin >> aa[1] >> aa[2] >> aa[3] >> aa[4]){
        memset(A,0,sizeof(A));
        int len = 0;
        for (int i = 1; i<=4; i++){
            getA(aa[i],i);
            len += aa[i];
        }
        int l = 1;
        while (l < 2 * (len + 1)) l<<=1; // l 为扩展长度
        conv(A[1],A[2],l);
        conv(A[1],A[3],l);
        conv(A[1],A[4],l);
        long long ans = 0;
        long long  f=1;
        for (int i = 1; i<=len ; i++){
            if ((len-i) % 2 ) f = -1LL;
            else f = 1LL;
            ans = (ans + f * F[i] * A[1][i] % MOD + MOD )%MOD;
        }
        cout << (ans % MOD ) << endl;
    }
}
View Code

复赛

Arithmetic of Bomb 模拟

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
long long yw[20000];
int main()
{
    int T;
    cin >> T;
    yw[0] = 1;
    for (int i = 1;i<=9999;i++)
    {
        yw[i] = (yw[i-1]*10)%mod;
    }
    while (T--)
    {
        string s;
        cin >> s;
        long long ans = 0;
        for (int i = 0; i<s.length();i++){
            if (s[i] == '(')
            {
                int cnt = 0;
                long long p = 0;
                while (s[i+1]!=')') {
                    i++;
                    cnt++;
                    p = (p+(s[i]-'0')) % mod;
                    if (s[i+1]!=')') p = p*10 % mod;
                }
                i++;
                int tmp = s[i+3]-'0';
                for (int j = 1;j<=tmp;j++)
                    ans = (ans * yw[cnt] % mod + p) % mod;
                i+=4;
            }
            else{
                ans = (ans * 10 + (s[i] - '0')) % mod;
            }

        }
        cout << ans <<endl;
    }

    return 0;
}
View Code

Pokémon GO 找规律

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
long long F[10008];
long long po[10008];
int main()
{
    int T;
    cin >> T;
    F[1] = 2;
    F[2] = 12;
    po[0] = 1;
    for (int i = 1; i<=10000;i++)
        po[i] = (po[i-1]*2LL)% mod;
    for (int i = 3;i<=10000 ;i++)
        F[i] = ((((F[i-1]*2LL) % mod)+ (4LL * F[i-2]) % mod) % mod + po[i]) % mod;
    for (int i = 1; i<=T;i++)
    {
        long long n;
        cin >> n;
        if (n==1) {cout << 2 << endl;continue;}
        long long ans = (F[n] * 2LL) % mod;
        for (int i = 2; i<n;i++)
            ans = (ans + ((po[i]*F[n-i]) % mod + (po[n-i+1]*F[i-1]) % mod) % mod) % mod;
        cout << ans <<endl;
    }

    return 0;
}
View Code

Valley Numer 数位DP

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const long long mod = 1000000007;
typedef long long LL;
char s[105];
int tot[150];
int T, len;
LL f[3][105][100];
LL dfs(int fuckp, int pre, int flag, int fuckl, int fuckz)
{
    if(fuckp <= 0)
    {
        if(!fuckz) return 1;
        else return 0;
    }
    if(!fuckl && !fuckz && f[flag][fuckp][pre] != -1) return f[flag][fuckp][pre];
    int ed = (fuckl ? tot[fuckp] : 9);
    LL res = 0;
    for(int i = 0; i <= ed; i++)
    {
        if(flag == 1)
        {
            if(pre > i) continue;
            else res = (res + dfs(fuckp - 1, i, 1, fuckl && (i == ed), 0)) % mod;
        }
        else
        {
            if(fuckz)
            {
                if(i == 0) res = (res + dfs(fuckp - 1, i, 0, fuckl && (i == ed), 1)) % mod;
                else res = (res + dfs(fuckp - 1, i, 0, fuckl && (i == ed), 0)) % mod;
            }
            else
            {
                if(i > pre)
                    res = (res + dfs(fuckp - 1, i, 1, fuckl && (i == ed), 0)) % mod;
                else res = (res + dfs(fuckp - 1, i, 0, fuckl && (i == ed), 0)) % mod;
            }
        }
    }
    if(!fuckz && !fuckl) return f[flag][fuckp][pre] = res % mod;
    return res % mod;
}

int main()
{
    for (scanf("%d", &T); T; T --)
    {
        memset(tot, 0, sizeof(tot));
        memset(f, -1, sizeof f);
        scanf ("%s", s);
        len = strlen(s);
        int cnt = 0;
        for (int i = len - 1; i >= 0; i--)
            tot[++cnt] = s[i] - '0';
        cout << (dfs(cnt, 0, 0, 1, 1) % mod) << endl;
    }
    return 0;
}
View Code

Valley Numer II 状压DP

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
vector <int> E[40];
vector <int> EB[40];
vector <int> w;
int id[40];
int hh[40];
int dp[40][70000];
int main()
{
    int T;
    cin >> T;
    while (T--){
        int N,M,K;
        cin >> N >> M >>K;
        memset(hh,0,sizeof(hh));
        memset(dp,-1,sizeof(dp));
        w.clear();
        for (int i = 1; i<=N;i++) E[i].clear(),EB[i].clear();
        for (int i = 1 ; i<=M; i++){
            int a,b;
            cin >> a >> b;
            E[a].push_back(b);
            E[b].push_back(a);
        }
        for (int i = 1; i<=K;i++){
            int a;cin >> a;
            hh[a]=1;
        }
        int cnt = 0;
        for (int i = 1; i <= N; i++){
            if (hh[i]) id[i] = cnt++;
            else w.push_back(i);
        }
        int sizew = w.size();
        for (int i = 1;i<=N ;i++){
            if (hh[i]) continue;
            for (int j = 0; j<E[i].size(); j++)
                if (hh[E[i][j]]) EB[i].push_back(E[i][j]);
        }
        // DP
        dp[0][0] = 0;
        int v1,v2;
        int top = 1<<(cnt);
        for (int i = 1; i<=sizew ;i++){
            int u = w[i-1];
            for (int s = 0 ; s < top ; s++){
                dp[i][s] = max(dp[i-1][s],dp[i][s]);
                if (dp[i-1][s] == -1) continue;
                for (int j = 0;j<EB[u].size(); j++){
                    v1 = EB[u][j];
                    if (( s & (1<<id[v1]) ) != 0) continue;
                    for (int k = j+1; k<EB[u].size() ; k++){
                        v2 = EB[u][k];
                        if (( s & (1<<id[v2]) ) != 0) continue;
                        dp[i][s | (1<<id[v1]) | (1<<id[v2])] = max(dp[i-1][s] + 1,dp[i][s | (1<<id[v1]) | (1<<id[v2])]);
                    }
                }
            }
        }
        int ans = 0;
        for (int s=0;s<top;s++){
            ans = max(dp[sizew][s],ans);
        }
        cout << ans <<endl;
    }
    return 0;
}
View Code
posted @ 2017-08-21 13:46  HITLJR  阅读(202)  评论(0编辑  收藏  举报