Codeforces Round #279 (Div. 2)(good)

隔了好久才补上这场,感觉这场总体还不错

C. Hacking Cypher
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarpus participates in a competition for hacking into a new secure messenger. He's almost won.

Having carefully studied the interaction protocol, Polycarpus came to the conclusion that the secret key can be obtained if he properly cuts the public key of the application into two parts. The public key is a long integer which may consist of even a million digits!

Polycarpus needs to find such a way to cut the public key into two nonempty parts, that the first (left) part is divisible bya as a separate number, and the second (right) part is divisible byb as a separate number. Both parts should bepositive integers that have no leading zeros. Polycarpus knows valuesa and b.

Help Polycarpus and find any suitable method to cut the public key.

Input

The first line of the input contains the public key of the messenger — an integer without leading zeroes, its length is in range from1 to 106 digits. The second line contains a pair of space-separated positive integersa, b (1 ≤ a, b ≤ 108).

Output

In the first line print "YES" (without the quotes), if the method satisfying conditions above exists. In this case, next print two lines — the left and right parts after the cut. These two parts, being concatenated, must be exactly identical to the public key. The left part must be divisible by a, and the right part must be divisible by b. The two parts must be positive integers having no leading zeros. If there are several answers, print any of them.

If there is no answer, print in a single line "NO" (without the quotes).

Sample test(s)
Input
116401024
97 1024
Output
YES
11640
1024
Input
284254589153928171911281811000
1009 1000
Output
YES
2842545891539
28171911281811000
Input
120
12 1
Output
NO
思路:类似于字符串hash的方法,先预处理出对a,b的余数,然后枚举每个位置,看分成的两端是否符合要求

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1000010;
char s[maxn];
int a,b,len;
LL res1[maxn],res2[maxn],xp[maxn];
bool solve()
{
    for(int i=0;i<len;i++)
    {
        if(res1[i]%a!=0||i==len-1||s[i+1]=='0')continue;
        if(((res2[len-1]-res2[i]*xp[len-1-i]%b)+b)%b==0)
        {
            printf("YES\n");
            for(int j=0;j<=i;j++)printf("%c",s[j]);
            printf("\n");
            for(int j=i+1;j<len;j++)printf("%c",s[j]);
            printf("\n");
            return true;
        }
    }
    return false;
}
int main()
{
    while(scanf("%s",s)!=EOF)
    {
        scanf("%d%d",&a,&b);
        len=strlen(s);
        xp[0]=1;
        for(int i=1;i<maxn;i++)xp[i]=(xp[i-1]*10)%b;
        res1[0]=(s[0]-'0')%a;
        res2[0]=(s[0]-'0')%b;
        for(int i=1;i<len;i++)
        {
            res1[i]=(res1[i-1]*10%a+s[i]-'0')%a;
            res2[i]=(res2[i-1]*10%b+s[i]-'0')%b;
        }
        if(!solve())printf("NO\n");
    }
    return 0;
}

思路:其实就是看这两个数因子2和3差多少就行了,注意判完3的记得不多出来的2加上

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int INF=1000000000;
LL a[4],res[4];
bool flag;
int ansnum;
LL anssize;
int cnt1[4],cnt2[4];
bool solve()
{
    memset(cnt1,0,sizeof(cnt1));
    memset(cnt2,0,sizeof(cnt2));
    for(int i=0;i<4;i++)
    {
        int t=a[i];
        while(t%2==0)
            t/=2,cnt1[i]++;
        while(t%3==0)
            t/=3,cnt2[i]++;
        res[i]=t;
    }
    if(res[0]*res[1]!=res[2]*res[3])return false;
    int tmp=cnt2[2]+cnt2[3]-cnt2[1]-cnt2[0];
    if(tmp>0)
    {
        int t=tmp;
        while(t>0&&a[2]%3==0)
            t--,a[2]=a[2]*2/3;
        while(t>0&&a[3]%3==0)
            t--,a[3]=a[3]*2/3;
    }
    else
    {
        int t=-tmp;
        while(t>0&&a[0]%3==0)
            t--,a[0]=a[0]*2/3;
        while(t>0&&a[1]%3==0)
            t--,a[1]=a[1]*2/3;
    };
    int tmp1=cnt1[2]+cnt1[3]-cnt1[0]-cnt1[1]+tmp;
    if(tmp1>0)
    {
        int t=tmp1;
        while(t>0&&a[2]%2==0)
            t--,a[2]/=2;
        while(t>0&&a[3]%2==0)
            t--,a[3]/=2;
    }
    else
    {
        int t=-tmp1;
        while(t>0&&a[0]%2==0)
            t--,a[0]/=2;
        while(t>0&&a[1]%2==0)
            t--,a[1]/=2;
    }
    printf("%d\n",abs(tmp)+abs(tmp1));
    cout<<a[0]<<" "<<a[1]<<endl<<a[2]<<" "<<a[3]<<endl;
    return true;
}
int main()
{
    while(cin>>a[0]>>a[1]>>a[2]>>a[3])
        if(!solve())printf("-1\n");
    return 0;
}

思路:字符串模拟

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=100010;
char s[maxn][15],ans[maxn][15];
int N;
bool solve(int pos,int i)
{
    for(int j=pos;j>=0;j--)
    {
        if(s[i-1][j]=='?'&&s[i][j]!='?'&&ans[i][j]!='0')
        {
            ans[i-1][j]=ans[i][j]-1;
            if(j==0&&ans[i-1][j]=='0')return false;
            for(int k=j+1;k<=pos;k++)
                if(s[i-1][k]=='?')ans[i-1][k]='9';
            return true;
        }
        if(s[i][j]=='?'&&s[i-1][j]=='?'&&ans[i][j]!='0')
        {
            ans[i-1][j]=ans[i][j]-1;
            if(j==0&&ans[i-1][j]=='0')return false;
            for(int k=j+1;k<=pos;k++)
                if(s[i-1][k]=='?')ans[i-1][k]='9';
            return true;
        }
    }
    return  false;
}
int main()
{
    while(scanf("%d",&N)!=EOF)
    {
        for(int i=1;i<=N;i++)scanf("%s",s[i]);
        if(N==1)
        {
            int len=strlen(s[1]);
            for(int i=0;i<len;i++)
                if(s[1][i]=='?')s[1][i]='9';
            printf("YES\n%s\n",s[1]);
            continue;
        }
        for(int i=1;i<=N;i++)
        {
            int len=strlen(s[i]);
            for(int j=0;j<=len;j++)ans[i][j]=s[i][j];
        }
        bool flag=true;
        for(int i=N;i>1;i--)
        {
            if(strlen(ans[i])<strlen(ans[i-1]))
            {
                flag=false;
                break;
            }
            int len=strlen(ans[i-1]);
            bool is_g=(strlen(ans[i])==strlen(ans[i-1])?false:true);
            for(int j=0;j<len;j++)
            {
                if(ans[i][j]=='?'&&ans[i-1][j]=='?')ans[i][j]=ans[i-1][j]='9';
                else if(ans[i][j]=='?'&&ans[i-1][j]!='?')
                {
                    if(ans[i-1][j]<'9')is_g=true;
                    ans[i][j]='9';
                }
                else if(ans[i][j]!='?'&&ans[i-1][j]=='?')
                {
                    if(is_g)ans[i-1][j]='9';
                    else ans[i-1][j]=ans[i][j];
                }
                else
                {
                    if(ans[i][j]<ans[i-1][j]&&!is_g)
                    {
                        if(!solve(j-1,i))
                        {
                            flag=false;
                            break;
                        }
                        is_g=true;
                    }
                    else if(ans[i][j]>ans[i-1][j])is_g=true;
                }
            }
            if(!is_g&&strlen(s[i])==strlen(s[i-1]))
            {
                if(!solve(len-1,i))
                {
                    flag=false;
                    break;
                }
            }
            if(!flag)break;
            for(int j=len;j<strlen(ans[i]);j++)
                if(ans[i][j]=='?')ans[i][j]='9';
        }
        if(!flag)printf("NO\n");
        else
        {
            printf("YES\n");
            for(int i=1;i<=N;i++)printf("%s\n",ans[i]);
        }
    }
    return 0;
}


F. Treeland Tour
time limit per test
5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The "Road Accident" band is planning an unprecedented tour around Treeland. The RA fans are looking forward to the event and making bets on how many concerts their favorite group will have.

Treeland consists of n cities, some pairs of cities are connected by bidirectional roads. Overall the country has n - 1 roads. We know that it is possible to get to any city from any other one. The cities are numbered by integers from 1 to n. For every city we know its value ri — the number of people in it.

We know that the band will travel along some path, having concerts in some cities along the path. The band's path will not pass one city twice, each time they move to the city that hasn't been previously visited. Thus, the musicians will travel along some path (without visiting any city twice) and in some (not necessarily all) cities along the way they will have concerts.

The band plans to gather all the big stadiums and concert halls during the tour, so every time they will perform in a city which population is larger than the population of the previously visited with concert city. In other words, the sequence of population in the cities where the concerts will be held is strictly increasing.

In a recent interview with the leader of the "road accident" band promised to the fans that the band will give concert in the largest possible number of cities! Thus the band will travel along some chain of cities of Treeland and have concerts in some of these cities, so that the population number will increase, and the number of concerts will be the largest possible.

The fans of Treeland are frantically trying to figure out how many concerts the group will have in Treeland. Looks like they can't manage without some help from a real programmer! Help the fans find the sought number of concerts.

Input

The first line of the input contains integer n (2 ≤ n ≤ 6000) — the number of cities in Treeland. The next line contains n integers r1, r2, ..., rn (1 ≤ ri ≤ 106), where ri is the population of the i-th city. The next n - 1 lines contain the descriptions of the roads, one road per line. Each road is defined by a pair of integers aj, bj (1 ≤ aj, bj ≤ n) — the pair of the numbers of the cities that are connected by the j-th road. All numbers in the lines are separated by spaces.

Output

Print the number of cities where the "Road Accident" band will have concerts.

Sample test(s)
Input
6
1 2 3 4 5 1
1 2
2 3
3 4
3 5
3 6
Output
4
Input
5
1 2 3 4 5
1 2
1 3
2 4
3 5
Output
3



思路:枚举每个起点,树上的LIS

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=6010;
const int INF=(1<<30);
int dp[maxn],N;
int a[maxn];
vector<int> g[maxn];
int ans;
void dfs(int id,int fa)
{
    int k=lower_bound(dp,dp+N,a[id])-dp;
    ans=max(ans,k);
    int tmp=dp[k];
    dp[k]=a[id];
    int len=g[id].size();
    for(int i=0;i<len;i++)
    {
        if(g[id][i]==fa)continue;
        dfs(g[id][i],id);
    }
    dp[k]=tmp;
}
int main()
{
    while(scanf("%d",&N)!=EOF)
    {
        for(int i=1;i<=N;i++)
        {
            dp[i]=INF;
            scanf("%d",&a[i]);
            g[i].clear();
        }
        for(int i=1;i<N;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        ans=1;
        for(int i=1;i<=N;i++)
            dfs(i,0);
        printf("%d\n",ans);
    }
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值