2017CCPC网络选拔赛

1007:第一个过的题,数位DP

#include
using namespace std;
typedef long long ll;
typedef pair P;
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define clr(x,y) memset(x,y,sizeof x)
#define PI acos(-1.0)
const int Mod = 1e9 + 7;
const int maxn = 100 + 10;
int k;
int bits[maxn];

int dight[40],tmp[40];
long long dp[40][40][100][100];
long long dfs(int k,int start,int pos,int s,bool limit)
{
    if(pos<0)
        return s;
    if(!limit&&dp[k][pos][s][start]!=-1)
        return dp[k][pos][s][start];
    int end;
    long long ret=0;
    if(limit)
        end=dight[pos];
    else
        end= k - 1;
    for(int d=0; d<=end; ++d)
    {
        tmp[pos]=d;
        if(start==pos&&d==0)
            ret+=dfs(k,start-1,pos-1,s,limit&&d==end);
        else if(s&&pos<(start+1)/2)
            ret+=dfs(k,start,pos-1,tmp[start-pos]==d,limit&&d==end);
        else
            ret+=dfs(k,start,pos-1,s,limit&&d==end);
    }
    if(!limit)
        dp[k][pos][s][start]=ret;
    return ret;
}
long long calc(ll k,long long a)
{
    memset(dight,0,sizeof(dight));
    int cnt=0;
    while(a!=0)
    {
        dight[cnt++]=a%k;
        a/=k;
    }
    return dfs(k,cnt-1,cnt-1,1,1);
}
int main()
{
    int Tcase;scanf("%d",&Tcase);clr(dp,-1);
    for(int ii = 1; ii <= Tcase; ii ++)
    {
        ll L,R,l,r;scanf("%I64d%I64d%I64d%I64d",&L,&R,&l,&r);
        ll ans = 0;
        for(int i = l; i <= r;i ++)
        {
            ll t = calc(i,R) - calc(i,L - 1);
//            cout << t << endl;
            ans += t * i + (R - L + 1-0 - t);
        }
        printf("Case #%d: %I64d\n",ii,ans);
    }
    return 0;
}
1003:猜了结论,暴力特判小于20的,大于20的直接bad,然后过了。。。比完赛后说有定理,大于6就不行。。。

#include 
using namespace std;

int T, n, v, a, b, G[300][300];
int in()
{
    char ch;
    int a = 0;
    while((ch = getchar()) == ' ' || ch == '\n');
    a += ch - '0';
    while((ch = getchar()) != ' ' && ch != '\n')
    {
        a *= 10;
        a += ch - '0';
    }
    return a;
}
bool ok()
{
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            for(int k = 1; k <= n; k++){
                if((i != j && i != k && j != k) && ((G[i][j] && G[i][k] && G[j][k]) || (!G[i][j] && !G[i][k] && !G[j][k]))) return false;
            }
        }
    }
    return true;
}

int main()
{
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        if(n > 20){
            int vv;
                for(int i = 1; i <= n; i++){
                for(int j = i + 1; j <= n; j++){
                    vv = in();
                }
            }
            puts("Bad Team!");
            continue;
        }
        memset(G, 0, sizeof(G));
        for(int i = 1; i <= n; i++){
            for(int j = i + 1; j <= n; j++){
                v = in();
                G[i][j] = v;
                G[j][i] = v;
            }
        }
        if(ok()) printf("Great Team!\n");
        else printf("Bad Team!\n");
    }

    return 0;
}
1005:打表到1e5。。。

#include
#define ll long long
#define ffff  lower_bound 

using namespace std;

double a[10010010];

int main()
{
    ll q = 8,qs = 8,qb = 2;
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    a[4] = 2;
    a[5] = 2;
    a[6] = 4;
    a[7] = 5;
    a[8] = 8;
    
    ll fff  = 1e5;
    for(int i = 9;i<=fff;i++)
    {
        
        
        if((i-q) == 1)
        {
            a[i] = (double)qs+(double)(2*qb-1)*0.5;
        }
        else if((i-q) == 2)
        {
            a[i] = (double)qs+(double)qb*2;
        }
        else if((i-q) == 3)
        {
            a[i] = (double)a[i-1]+(double)(2*(qb+1)-1)*0.5;
        }
        else if((i-q) == 4)
        {
            a[i] = (double)qs+(double)qb*2+((double)qb+1)*2;
                q = i;
                qs = a[i];
                qb = qb+1;
        }
        
    
        
     } 
//    printf("%.2f\n",a[100000]);
     int Tcase;

     scanf("%d",&Tcase);
     while(Tcase--)
     {
         double mm;
         scanf("%lf",&mm);
         int ans = ffff(a,a+100000,mm) - a;
         printf("%d\n",ans);
         
     }
     




 return 0;
}
1004:二分加哈希。。卡着时间过的,正解应该是kmp加二分

#include 
#include 
#include 
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 1;
const ull b=131;
char s1[maxn],s2[maxn],s3[maxn];
ull hash1[maxn],hash2[maxn],bit[maxn];
int main()
{
    bit[0]=1;
    for(int i=1;i<=1000000;i++)
        bit[i]=bit[i-1]*b;
    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s3+1);ll ans=0;
        int l1=strlen(s3+1);
        for(int i=1;i<=l1;i++)s1[i]=s3[l1-i+1];
        scanf("%s",s3+1);int l2=strlen(s3+1);
        for(int i=1;i<=l2;i++)s2[i]=s3[l2-i+1];
        for(int i=1;i<=l1;i++)hash1[i]=hash1[i-1]*b+s1[i];
        for(int i=1;i<=l2;i++)hash2[i]=hash2[i-1]*b+s2[i];
        for(int i=1;i<=l1;i++)
        {
            int l=0,r=min(l2,l1-i+1)+1;
            while(r-l>1)
            {
                int mid=(l+r)>>1;
                if(mid-1+i>l1){r=mid;continue;}
                if(hash1[i+mid-1]-hash1[i-1]*bit[mid]==hash2[mid]-hash2[0]*bit[mid])
                    l=mid;
                else
                    r=mid;
            }
            ans+=(long long)l*(l+1)/2;
            ans%=mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

能不能出线。。看运气吧!



你可能感兴趣的:(2017CCPC)