1. 程式人生 > >2017 ACM/ICPC Asia Regional Qingdao Online

2017 ACM/ICPC Asia Regional Qingdao Online

bottom subst 中國 == key 機房 mil turn total

The Dominator of Strings

Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 6778 Accepted Submission(s): 713


Problem Description Here you have a set of strings. A dominator is a string of the set dominating all strings else. The string S is dominated by T
if S is a substring of T.

Input The input contains several test cases and the first line provides the total number of cases.
For each test case, the first line contains an integer N indicating the size of the set.
Each of the following N lines describes a string of the set in lowercase.
The total length of strings in each case has the limit of 100000
.
The limit is 30MB for the input file.

Output For each test case, output a dominator if exist, or No if not.

Sample Input 3 10 you better worse richer poorer sickness health death faithfulness youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness 5 abc cde abcde abcde bcde 3 aaaaa aaaab aaaac

Sample Output youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness abcde No 從較長串中找子串的 自動機的復雜度太高,挑戰上的代碼就可以過得
#include<bits/stdc++.h>
  
using namespace std;  
const int MAXN = 100010;  
int n,k;  
int Paiming[MAXN+1],tmp[MAXN+1];  
int flag;  
bool comp_sa(int i, int j)  
{  
    if(Paiming[i] != Paiming[j])   
        return Paiming[i] < Paiming[j];  
    else{
        int ri = i+k <= n? Paiming[i+k] : -1;  
        int rj = j+k <= n? Paiming[j+k] : -1;  
        return ri < rj;     
    }  
}  
  
void calc_sa(string &S, int *sa) 
{  
    n = S.size();  
    for(int i = 0; i <= n; i++)  
    {  
        sa[i] = i;  
        Paiming[i] = i < n ? S[i] : -1;  
    }  
      
    for( k =1; k <= n; k *= 2)  
    {  
        sort(sa,sa+n+1,comp_sa);  
        tmp[sa[0]] = 0;  
        for(int i = 1; i <= n; i++)  
        {  
            tmp[sa[i]] = tmp[sa[i-1]] + (comp_sa(sa[i-1],sa[i]) ? 1: 0);  
        }  
        for(int i = 0; i <= n; i++)  
        {  
            Paiming[i] = tmp[i];  
        }  
    }  
}  
  
int SuffixArrayMatch(string &S, int *sa, string T)  
{  
    
    int lhs = 0, rhs = S.size();  
    while(rhs - lhs > 1)  
    {  
        int mid = (lhs + rhs)>>1;  
        if(S.compare(sa[mid],T.size(),T) < 0) lhs = mid;
        else rhs=mid;   
    }
    return S.compare(sa[rhs],T.size(),T) == 0;  
}  
int main()  
{  
    int t;
    ios::sync_with_stdio(false);
    cin>>t;        
    string s[100010],longs;    
    while(t--){
        int n,l=-1,p=-1,i; 
        cin>>n;
        memset(Paiming,0,sizeof Paiming);
        memset(tmp,0,sizeof tmp);
        for(i=0;i<n;i++){
            cin>>s[i];
            int len=s[i].size();
            if(len>l){
                l=len;
                longs=s[i];
                p=i;
            }
        }
        if(n==1){
            cout<<longs<<endl;
            continue;
        }   
        int *sa = new int[longs.size()+1];  
        calc_sa(longs,sa);
        for(i=0;i<n;i++){
            if(p==i)continue;    
            if(!SuffixArrayMatch(longs,sa,s[i]))
            break;  
        } 
        //delete [] sa;  
        sa = NULL; 
        if(i>=n){
            cout<<longs<<endl;
        }else {
            cout<<"No"<<endl;
        }      
    }   
}  

Chinese Zodiac

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 2451 Accepted Submission(s): 1645


Problem Description The Chinese Zodiac, known as Sheng Xiao, is based on a twelve-year cycle, each year in the cycle related to an animal sign. These signs are the rat, ox, tiger, rabbit, dragon, snake, horse, sheep, monkey, rooster, dog and pig.
Victoria is married to a younger man, but no one knows the real age difference between the couple. The good news is that she told us their Chinese Zodiac signs. Their years of birth in luner calendar is not the same. Here we can guess a very rough estimate of the minimum age difference between them.
If, for instance, the signs of Victoria and her husband are ox and rabbit respectively, the estimate should be 2 years. But if the signs of the couple is the same, the answer should be 12 years.
Input The first line of input contains an integer T (1T1000) indicating the number of test cases.
For each test case a line of two strings describes the signs of Victoria and her husband.

Output For each test case output an integer in a line.
Sample Input 3 ox rooster rooster ox dragon dragon
Sample Output 8 4 12 中國生肖,隨手模擬就可以了
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
int main()
{
    char m[12][10]={
        "rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "sheep", "monkey", "rooster", "dog" , "pig"
    };
    int t,s;
    scanf("%d",&t);
    while(t--){
        char p[10],q[10];
        scanf("%s%s",&p,&q);
        if(strcmp(p,q)==0){
            puts("12");
        }else {
            int i,pp,qq;
            for(i=0;i<12;i++){
                if(strcmp(m[i],p)==0){
                    pp=i;
                }
                if(strcmp(m[i],q)==0){
                    qq=i;
                }
            }
            s=(pp-qq);
            if(s>0){
                s=s-12;
            }
            printf("%d\n",-s);
        }
    }
} 

Smallest Minimum Cut

Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3297 Accepted Submission(s): 602


Problem Description Consider a network G=(V,E) with source s and sink t. An s-t cut is a partition of nodes set V into two parts such that s and t belong to different parts. The cut set is the subset of E with all edges connecting nodes in different parts. A minimum cut is the one whose cut set has the minimum summation of capacities. The size of a cut is the number of edges in the cut set. Please calculate the smallest size of all minimum cuts.
Input The input contains several test cases and the first line is the total number of cases T (1T300).
Each case describes a network G, and the first line contains two integers n (2n200) and m (0m1000) indicating the sizes of nodes and edges. All nodes in the network are labelled from 1 to n.
The second line contains two different integers s and t (1s,tn) corresponding to the source and sink.
Each of the next m lines contains three integers u,v and w (1w255) describing a directed edge from node u to v with capacity w.

Output For each test case, output the smallest size of all minimum cuts in a line.
Sample Input 2 4 5 1 4 1 2 3 1 3 1 2 3 1 2 4 1 3 4 2 4 5 1 4 1 2 3 1 3 1 2 3 1 2 4 1 3 4 3 Sample Output 2 3 求點s到點t的最小割,這個網上就有一道一樣的題吧 dinic是過不去的,要用sap算法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAXN 2333
#define MAXM 2333333
struct Edge
{
    int v,next;
    ll cap;
} edge[MAXM];
int head[MAXN],pre[MAXN],cur[MAXN],level[MAXN],gap[MAXN],NV,NE,n,m,vs,vt;
void ADD(int u,int v,ll cap,ll cc=0)
{
    edge[NE].v=v;
    edge[NE].cap=cap;
    edge[NE].next=head[u];
    head[u]=NE++;

    edge[NE].v=u;
    edge[NE].cap=cc;
    edge[NE].next=head[v];
    head[v]=NE++;
}
ll SAP(int vs,int vt)
{
    memset(pre,-1,sizeof(pre));
    memset(level,0,sizeof(level));
    memset(gap,0,sizeof(gap));
    for(int i=0; i<=NV; i++)cur[i]=head[i];
    int u=pre[vs]=vs;
    ll aug=-1,maxflow=0;
    gap[0]=NV;
    while(level[vs]<NV)
    {
loop:
        for(int &i=cur[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(edge[i].cap&&level[u]==level[v]+1)
            {
                aug==-1?aug=edge[i].cap:aug=min(aug,edge[i].cap);
                pre[v]=u;
                u=v;
                if(v==vt)
                {
                    maxflow+=aug;
                    for(u=pre[u]; v!=vs; v=u,u=pre[u])
                    {
                        edge[cur[u]].cap-=aug;
                        edge[cur[u]^1].cap+=aug;
                    }
                    aug=-1;
                }
                goto loop;
            }
        }
        int minlevel=NV;
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(edge[i].cap&&minlevel>level[v])
            {
                cur[u]=i;
                minlevel=level[v];
            }
        }
        if(--gap[level[u]]==0)break;
        level[u]=minlevel+1;
        gap[level[u]]++;
        u=pre[u];
    }
    return maxflow;
}

int main()
{
    int T,u,v,w;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        scanf("%d%d",&vs,&vt);
        NV=n,NE=0;
        memset(head,-1,sizeof(head));
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            ADD(u,v,(ll)w*MAXM+1);
        }
        ll ans=SAP(vs,vt);
        printf("%d\n",ans%MAXM);
    }
    return 0;
}

A Cubic number and A Cubic Number

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 4947 Accepted Submission(s): 1346


Problem Description A cubic number is the result of using a whole number in a multiplication three times. For example, 3×3×3=27 so 27 is a cubic number. The first few cubic numbers are 1,8,27,64 and 125. Given an prime number p. Check that if p is a difference of two cubic numbers.
Input The first of input contains an integer T (1T100) which is the total number of test cases.
For each test case, a line contains a prime number p (2p1012).

Output For each test case, output ‘YES‘ if given p is a difference of two cubic numbers, or ‘NO‘ if not.
Sample Input 10 2 3 5 7 11 13 17 19 23 29
Sample Output NO NO NO YES NO NO NO YES NO 這個我是機房第一個做出來的啊,讓你看一個數是不是兩個數的立方差 但是這個數是質數,因式分解判斷另一段就好的 直接二分答案存不存在就好
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
bool la(LL x)
{
    LL l=1,r=1e6+5;
    while(l<=r)
    {
        LL mi=(l+r)/2;
        LL y=mi-1;
        if(mi*mi+y*y+mi*y==x)
            return 1;
        else if(mi*mi+y*y+mi*y<x)
            l=mi+1;
        else r=mi-1;
    }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        LL n;
        scanf("%lld",&n);
        printf("%s\n",la(n)?"YES":"NO");
    }
    return 0;
}

2017 ACM/ICPC Asia Regional Qingdao Online