隔了好久才补上这场,感觉这场总体还不错
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.
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).
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).
116401024 97 1024
YES 11640 1024
284254589153928171911281811000 1009 1000
YES 2842545891539 28171911281811000
120 12 1
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;
}
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.
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.
Print the number of cities where the "Road Accident" band will have concerts.
6 1 2 3 4 5 1 1 2 2 3 3 4 3 5 3 6
4
5 1 2 3 4 5 1 2 1 3 2 4 3 5
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;
}