没想到身为菜鸟的我也能做7题,嘿嘿嘿
2018/10/9 填坑完毕hhh
A-送分题:https://www.nowcoder.com/acm/contest/190/A
思路:该题直接交会爆内存。。。观察(跑几组数据)发现只要n大于等于2018001就都为 20182017,其他的则为 n+2017
Code :
#include<iostream>
using namespace std;
int main()
{
long long n;
cin >> n;
if(n<20180001) cout<<n+2017<<endl;
else cout << 20182017 << endl;
return 0;
}
B-自杀游戏:https://www.nowcoder.com/acm/contest/190/B
思路:可以用dp来做,对于dp[i],只要它能够转移到必败的状态,那么dp[i]一定是必胜的,否则就是必败的
Code:
#include<iostream>
using namespace std;
const int MAX_N=100005;
int a,b,n;
int dp[MAX_N];
int main()
{
while(cin>>n>>a>>b){
++a; ++b;
dp[0]=-1;
for(int i=1;i<=n;++i)
{
if(dp[i-1]==-1){
dp[i]=1;
}else{
if(i<a) dp[i]=-1;
for(int j=a;j<=b;++j)
if(i>=j&&dp[i-j]==-1){
dp[i]=1; break;
}
if(dp[i]!=1) dp[i]=-1;
}
}
if(dp[n]==1) cout<<"Alice"<<endl;
else cout<<"Bob"<<endl;
}
return 0;
}
C-谁是神枪手:https://www.nowcoder.com/acm/contest/190/C
思路:不难求出,对于A胜概率 Pa,B胜概率 Pb为
B胜条件 Pb-Pa>0 最后可化为 (100-a)*b>100*a
那么平局时(100-a)*b=100*a
A胜:(100-a)*b<100*a
Code :
#include<iostream>
using namespace std;
int a,b;
int main()
{
while(cin>>a>>b){
if((100-a)*b>100*a) cout<<"CSL"<<endl;
else if((100-a)*b==100*a) cout<<"equal"<<endl;
else cout<<"MWH"<<endl;
}
return 0;
}
D-明七暗七:https://www.nowcoder.com/acm/contest/190/D
思路:数位DP+二分。利用数位DP可以求出从1到n的满足条件的个数,而对于求具体的数字,则可以用二分查找来求解
dp[i][j][k]: 前i位余数为j,是否有7的个数
Code :
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
LL n,m;
int a[20];
LL dp[20][10][2];
LL Find(LL p);
LL DFS(int k,int mod,int boo,int bo);
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m){
memset(dp,-1,sizeof(dp));
LL l=n,r=1e14,t=Find(n);
while(l<=r){
LL h=(l+r)/2;
if(Find(h)-t>=m) r=h-1;
else l=h+1;
}
cout<<l<<endl;
}
return 0;
}
LL Find(LL p)
{
int pre=0;
while(p){
a[pre++]=p%10;
p/=10;
}
return DFS(pre-1,0,0,1);
}
LL DFS(int k,int mod,int boo,int bo) //第k位,余数mod,boo是否有7,bo是否为p
{
LL ans=0;
if(k==-1) ans=(!mod)||boo;
else if(dp[k][mod][boo]!=-1&&!bo) ans=dp[k][mod][boo];
else{
int pre=bo?a[k]:9;
for(int i=0;i<=pre;++i)
ans+=DFS(k-1,(mod*10+i)%7,boo||i==7,bo&&i==a[k]);
if(!bo) dp[k][mod][boo]=ans;
}
return ans;
}
E-Applese的超能力: https://www.nowcoder.com/acm/contest/190/E
思路:对于m个硬币可合成 1个硬币,最后要只剩一个硬币,由最后n=1个硬币往后推,n=1+(m-1)个硬币成立,再是1+(m-1)可当成1个硬币,则还需要6个硬币 n= 1+(m-1)+(m-1)也成立,则n=1+(m-1)*k时为Yes,否则为No
Code :
#include<iostream>
using namespace std;
int n,m;
int main()
{
while(cin>>n>>m){
bool boo=false;
if(n==1||m!=1&&(n-1)%(m-1)==0) boo=true;
if(boo) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
F-BFS:https://www.nowcoder.com/acm/contest/190/F
思路:真水题
Code:
#include<iostream>
using namespace std;
string str;
int main()
{
while(cin>>str){
int len=str.size();
int boo=-1;
for(int i=0;i<len-2;++i)
if((str[i]=='B'||str[i]=='b')&&(str[i+1]=='O'||str[i+1]=='o')&&(str[i+2]=='B'||str[i+2]=='b')){
boo=i; break;
}
cout<<boo<<endl;
}
return 0;
}
G-CSL分苹果:https://www.nowcoder.com/acm/contest/190/G
思路:背包DP,dp[i]=1表示 背包中有 i质量的苹果。则对于每个苹果质量x, 若dp[i]=1,则dp[i+x]=1;最后查找离所有苹果质量和一半sum/2最近的dp[i]=1即可
Code :
#include<iostream>
using namespace std;
const int MAX_N=100;
const int MAX_S=10005;
int n;
int dp[MAX_S];
int main()
{
ios::sync_with_stdio(false);
cin>>n;
dp[0]=1;
int sum=0;
for(int i=1,x;i<=n;++i)
{
cin>>x;
sum+=x;
for(int j=MAX_S-x-1;j>=0;--j)
{
if(dp[j]){
dp[j+x]=1;
}
}
}
int ans=0;
for(int i=sum/2;i>=0;--i)
if(dp[i]){
ans=i; break;
}
cout<<ans<<" "<<sum-ans<<endl;
return 0;
}
H-CSL的校园卡:https://www.nowcoder.com/acm/contest/190/H
思路:状态压缩DP+BFS
用dp[x1][y1][x2][y2][s]来表示两人分别在点 (x1,y1),(x2,y2)处走过的状态s时的所用时间,那么再用BFS来找到第一个满足条件的即可
Code:
#include<iostream>
#include<queue>
using namespace std;
struct node{
int x1,y1;
int x2,y2;
int t,s;
};
const int MAX_S=(1<<16)+5;
const int f[][2]={-1,0, 1,0, 0,-1, 0,1};
int n,m,ans,Sum;
string G[5];
bool boo[5][5][5][5][MAX_S];
void BFS(int x,int y);
int main()
{
cin>>n>>m;
int x0,y0;
for(int i=0;i<n;++i)
{
cin>>G[i];
for(int j=0;j<m;++j)
if(G[i][j]=='S'){
x0=i; y0=j;
Sum+=(1<<(i*4+j));
}else if(G[i][j]=='O'){
Sum+=(1<<(i*4+j));
}
}
BFS(x0,y0);
cout<<ans<<endl;
return 0;
}
void BFS(int x,int y)
{
queue<node> Q;
Q.push(node{x,y,x,y,1<<(x*4+y),0});
boo[x][y][x][y][(1<<(x*4+y))]=1;
while(!Q.empty()){
int x1,y1,x2,y2;
node u=Q.front(); Q.pop();
for(int i=0;i<4;++i)
{
x1=u.x1+f[i][0]; y1=u.y1+f[i][1];
int t1=1<<(x1*4+y1);
if(x1>=0&&x1<n&&y1>=0&&y1<m&&G[x1][y1]!='X'){
for(int j=0;j<4;++j)
{
x2=u.x2+f[j][0]; y2=u.y2+f[j][1];
int t2=1<<(x2*4+y2);
if(x2>=0&&x2<n&&y2>=0&&y2<m&&G[x2][y2]!='X'){
int s=(t1|t2)|u.t;
if(!boo[x1][y1][x2][y2][s]){
Q.push(node{x1,y1,x2,y2,s,u.s+1});
boo[x1][y1][x2][y2][s]=1;
}
if(s==Sum){
ans=u.s+1;
return;
}
}
}
}
}
}
}
I-新建 Microsoft Office Word 文档:https://www.nowcoder.com/acm/contest/190/I
思路:利用优先队列Q来维护最小值,同时用数组boo[]来对已有文档序列做标记即可
Code:
#include<iostream>
#include<queue>
using namespace std;
const int MAX_N=100005;
int n,T;
string str;
priority_queue<int,vector<int>,greater<int> > Q;
bool boo[MAX_N];
int main()
{
cin>>T;
n=0;
int x;
while(T--){
cin>>str;
if(str=="New"){
if(!Q.empty()){
cout<<Q.top()<<endl;
boo[Q.top()]=true;
Q.pop();
}else{
boo[++n]=true;
cout<<n<<endl;
}
}else{
cin>>x;
if(boo[x]){
boo[x]=false;
Q.push(x);
cout<<"Successful"<<endl;
}else cout<<"Failed"<<endl;
}
}
return 0;
}
J-方格填色:https://www.nowcoder.com/acm/contest/190/J
思路:状态压缩+矩阵快速幂
对于状态压缩方程易得转换方程
for(int i=2;i<=n;++i)
for(int j=0;j<=s;++j)
for(int k=0;k<=s;++k)
if((j||k)&&!(j&k)) dp[i][j]=(dp[i][j]+dp[i-1][k])%MOD;
而对于转移方程可以用矩阵快速幂来优化,与骨牌覆盖类似https://blog.youkuaiyun.com/C_13579/article/details/82883625
Code :
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int MAX_S=35;
struct Matrix{
LL a[MAX_S][MAX_S];
Matrix(){memset(a,0,sizeof(a));}
Matrix operator*(const Matrix &A){
Matrix res=Matrix();
for(int k=0;k<MAX_S;++k)
for(int i=0;i<MAX_S;++i)
for(int j=0;j<MAX_S;++j)
res.a[i][j]=(res.a[i][j]+a[i][k]*A.a[k][j]%MOD)%MOD;
return res;
}
};
LL n,m;
int main()
{
ios::sync_with_stdio(false);
while(cin>>m>>n){
int s=(1<<m)-1;
Matrix t0=Matrix(),ans=Matrix();
for(int i=0;i<MAX_S;++i)
ans.a[i][i]=1;
for(int i=0;i<=s;++i)
for(int j=0;j<=s;++j)
if((i||j)&&!(i&j)) t0.a[i][j]=1;
--n;
while(n){
if(n&1) ans=ans*t0;
t0=t0*t0;
n>>=1;
}
LL res=0;
for(int i=0;i<=s;++i)
for(int j=0;j<=s;++j)
res=(res+ans.a[i][j])%MOD;
cout<<res<<endl;
}
return 0;
}