题目链接: http://acm.xidian.edu.cn/contest.php?cid=1038
在写这篇题解的时候其实现场赛都打完了,不过因为最近事比较多,一直没有写这篇题解。今天碰巧有空,又补了一波题(虽说最后还是没AK),下面进入正文~
-------------------------------------------------------------------------------------------------------------------------------
A题
大水题,直接贴代码
#include
using namespace std;
int main()
{
int n;
int c;
scanf("%d",&n);
for(int i=0;i
B题
水题,用gcd做即可
#include
using namespace std;
int gcd(int a,int b)
{
int maxn,minn;
if(a>=b)
{
maxn=a;
minn=b;
}
else
{
maxn=b;
minn=a;
}
int t;
while(minn)
{
t=maxn%minn;
maxn=minn;
minn=t;
}
return maxn;
}
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
{
printf("%d\n",gcd(a,b));
}
return 0;
}
C题
貌似使用前缀和做的,做了挺长时间了,有些忘了(逃)
#include
#include
using namespace std;
long long int a[100010];
long long int back[100010];
int main()
{
long long int n,m;
long long int sum;
long long int index;
while(scanf("%lld%lld",&n,&m)!=EOF)
{
sum=0;
for(long long int i=0;i=n/2;i--)
{
if(u*a[i]-back[i]<=m)
{
index=i;
m-=(u*a[i]-back[i]);
for(long long int j=n/2;j<=i;j++)
{
a[j]=a[i];
}
break;
}
u--;
}
long long int up=m/u;
printf("%lld\n",a[index]+up);
}
}
return 0;
}
D题
找规律,但这个规律十分好找,打个表就出来了~
#include
using namespace std;
long long int f(long long int x)
{
if(x<=100)
return f(f(x+11));
else
return x-10;
}
int main()
{
int n;
long long int t;
scanf("%d",&n);
while(n--)
{
scanf("%lld",&t);
if(t<=100)
printf("91\n");
else
printf("%lld\n",t-10);
}
return 0;
}
E题
我用的是bfs,这道题能过,但在现场赛一加强数据就被虐了(还是菜)~
#include
#include
using namespace std;
typedef struct
{
int s;
int na;
int nb;
} node;
int bfs(int r)
{
node n1;
n1.s=0;
n1.na=1;
n1.nb=1;
queue q;
q.push(n1);
while(!q.empty())
{
node tem=q.front();
q.pop();
if(tem.nb==r)
{
return tem.s;
}
node n2;
node n3;
if(tem.na+tem.nb<=r)
{
n2.na=tem.na;
n2.nb=tem.na+tem.nb;
n2.s=tem.s+1;
q.push(n2);
}
if(2*tem.nb<=r)
{
n3.na=tem.nb;
n3.nb=2*tem.nb;
n3.s=tem.s+1;
q.push(n3);
}
}
}
int main()
{
int n;
int t;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&t);
printf("%d\n",bfs(t));
}
return 0;
}
F题
赛后补出来的题,推一下递推式+矩阵快速幂,不过我的矩阵快速幂给写慢了,用了900多毫秒才过。。。
#include
#include
using namespace std;
typedef long long ll;
ll M=1e9+7;
typedef vector vec;
typedef vector mat;
mat mul(mat &A,mat &B)
{
int l1=A.size();
int l2=B[0].size();
int l3=B.size();
mat C(A.size(),vec(B[0].size()));
for(int i=0;i0)
{
if(n&1)
B=mul(B,A);
A=mul(A,A);
n>>=1;
}
return B;
}
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF)
{
mat A(3,vec(3));
A[0][0]=1;
A[0][1]=1;
A[0][2]=0;
A[1][0]=-1;
A[1][1]=0;
A[1][2]=1;
A[2][0]=1;
A[2][1]=1;
A[2][2]=1;
A=powmod(A,n);
ll t1;
t1=(A[0][0]+A[0][2])%M;
ll t2;
t2=(A[1][0]+A[1][2])%M;
ll ans;
ans=(t1+t2)%M;
if(ans<0)
ans+=M;
printf("%lld\n",ans);
}
return 0;
}
G题
一道八数码问题,bfs+康拓展开来压缩状态即可~
#include
#include
#include
using namespace std;
char biao[10]="012345678";
int bb[]={0,1,2,3,4,5,6,7,8};
char a[10];
int sx,sy;
int st;
int vis[370000];
int f[10] = {1,1,2,6,24,120,720,5040,40320,362880};
typedef struct
{
char c[10];
int cc[10];
int s;
int z;
int ct;
} node;
int Canton(int s[])
{
int sun = 0, tmp;
for (int i = 0; i < 9; i++)
{
tmp = 0;
for (int j = i + 1; j < 9; j++)
if (s[j] < s[i]) tmp++;
sun += (tmp * f[9 - i - 1]);
}
return sun + 1;
}
int bfs()
{
queue q;
node n1;
int dx[4]={1,-1,3,-3};
n1.s=0;
n1.z=st;
strcpy(n1.c,a);
for(int i=0;i<9;i++)
n1.cc[i]=n1.c[i]-'0';
n1.ct=Canton(n1.cc);
vis[n1.ct]=1;
q.push(n1);
while(!q.empty())
{
node tem=q.front();
q.pop();
if(strcmp(tem.c,biao)==0)
return tem.s;
// if(Canton(tem.cc)==Canton(bb))
// return tem.s;
for(int i=0;i<4;i++)
{
if(tem.z%3==0&&i==1)
continue;
if(tem.z%3==2&&i==0)
continue;
node n2;
n2.s=tem.s+1;
int tx=tem.z+dx[i];
n2.z=tx;
if(tx>=0&&tx<=8)
{
strcpy(n2.c,tem.c);
char t=n2.c[tx];
n2.c[tx]=n2.c[tem.z];
n2.c[tem.z]=t;
for(int i=0;i<9;i++)
n2.cc[i]=n2.c[i]-'0';
int tt=Canton(n2.cc);
if(vis[tt]==0)
{
q.push(n2);
vis[tt]=1;
}
}
}
}
return -1;
}
int main()
{
int n;
int t;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int u=0;
memset(vis,0,sizeof(vis));
for(int j=1;j<=3;j++)
{
for(int k=1;k<=3;k++)
{
scanf("%d",&t);
a[u]=t+'0';
if(t==0)
st=u;
u++;
}
}
a[9]='\0';
int res=bfs();
if(res!=-1)
printf("%d\n",res);
else
{
printf("cannot\n");
}
}
return 0;
}
H题
其实这是一道贪心题(证明的话不太容易),不过仔细想一想其实可以想出来~
就是排序,相邻的一定斜率最小,见代码:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef struct
{
int w;
int no;
} P;
P p[1000010];
bool cmp(P a,P b)
{
return a.w
I题(不会,待补。。。)
J题
赛后写出来的题,用了一个Markov过程(其实我之前不知道。。。),简单地说就是未来的状态只与现在有关,而与过去无关。仔细想一想,这题确实是这样的。然后就是推个期望的递推式。。。详见代码:
#include
#include
using namespace std;
double e[510];
int t;
double solve(int n)
{
double sum=0;
for(int i=0;i<=500;i++)
e[i]=0;
e[0]=0;
for(int i=1;i<=n;i++)
{
e[i]=(double)n/i;
for(int j=1;j<=i;j++)
{
e[i]+=(1.0/i)*e[i%j];
}
sum+=e[i];
}
return sum/n+1;
}
int main()
{
while(scanf("%d",&t)!=EOF)
printf("%.2lf\n",solve(t));
return 0;
}
最后附上xdoj上的题解(思路):
http://acm.xidian.edu.cn/download/2018-online-unofficial-editorial.pdf