预测:100+100+100+100=400
实际:100+0+100+0=200
T2是小细节,T4是它题面跟标题的文件名不一+细节错误
唉,下次再这样剁手
T1,子数整数,题目大意:
对于一个五位数 a1a2a3a4a5,可将其拆分为三个子数: sub1=a1a2a3
sub2=a2a3a4
sub3=a3a4a5
例如,五位数 20207 可以拆分成 sub1=202
sub2=020(=20) sub3=207
现在给定一个正整数 K,要求你编程求出 10000(包括 10000)到 30000(包括 30000)之间所有满足下述条件的五位数,条件是这些五位数的三个子数 sub1,sub2,sub3 都可被 K 整除。
要求从小到大输出。不得重复输出或遗漏。如果无解,则输出“-1”。
题解:
直接枚举判断即可。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int k;
int main()
{
scanf("%d",&k);
int sum=0;
for (int i=10000; i<=30000; i++)
{
int a1=i/100;
int b1=i/10%1000;
int c1=i%1000;
if (a1%k==0 && b1%k==0 && c1%k==0)
{
printf("%d\n",i);
sum++;
}
}
if (!sum) printf("%d\n",-1);
return 0;
}
T2,游戏问题,题目大意:
“五四”青年节到了,某学校要举行一个游园活动,其中有一个这样的游戏: n 个同学(编号从 0 到 n-1)围坐一圈,按照顺时针方向给 n 个位置编号,从0 到 n-1。最初,第 0 号同学在第 0 号位置,第 1 号同学在第 1 号位置,„„,
依此类推。
游戏规则如下:每一轮第 0 号位置上的同学顺时针走到第 m 号位置,第 1号位置同学走到第 m+1 号位置,„„,依此类推,第 n − m 号位置上的同学走到第 0 号位置,第 n-m+1 号位置上的同学走到第 1 号位置,„„,第 n-1 号位置上的同学顺时针走到第 m-1 号位置。
现在,一共进行了 10^k 轮,请问 x 号同学最后走到了第几号位置。
对于 30% 的数据,0 < k < 7;
对于 80% 的数据, 0 < k < 10^7;
对于 100% 的数据,
1 < n <1,000,000
0 < m < n
1 ≤ x ≤ n
0 < k < 10^9
题解:
因为每进行N轮则回到原点,所以只需要进行10^K mod N轮即可,这里用快速幂然后模拟一下即可,垃圾快速幂。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,x,k;
int ksm(int x,int y)
{
int rp=0;
while (y)
{
if (y%2)
{
if (!rp) rp=1;
rp=(rp%n)*x%n;
}
y=y/2;
x=(x%n)*x%n;
}
return rp;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&x);
int cp=ksm(10,k);
for (int i=1; i<=cp; i++)
{
x=x+m;
if (x>n-1) x=x-(n-1)-1;
}
printf("%d\n",x);
return 0;
}
T3,字串距离,题目大意:
设有字符串 X,我们称在 X 的头尾及中间插入任意多个空格后构成的新字符
串为 X 的扩展串,如字符串 X 为”abcbcd”,则字符串“abcb□cd”,“□a□bcbcd □”和“abcb□cd□”都是 X 的扩展串,这里“□”代表空格字符。
如果 A1 是字符串 A 的扩展串,B1 是字符串 B 的扩展串,A1 与 B1 具有相 同的长度,那么我扪定义字符串 A1 与 B1 的距离为相应位置上的字符的距离总 和,而两个非空格字符的距离定义为它们的 ASCII 码的差的绝对值,而空格字 符与其他任意字符之间的距离为已知的定值 K,空格字符与空格字符的距离为 0。
在字符串 A、B 的所有扩展串中,必定存在两个等长的扩展串 A1、B1,使得 A1 与 B1 之间的距离达到最小,我们将这一距离定义为字符串 A、B 的距离。
请你写一个程序,求出字符串 A、B 的距离。
A、B 均由小写字母组成且长度均不超过 2000
1≤K≤100
题解:
f[i][j]表示A前i位B前j位匹配后的最小值。
则可以推出,
f[i][j]=
min(f[i-1][j]+k,f[i][j-1]+k,f[i-1][j-1] + 差值)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 2005
using namespace std;
char u[N],v[N];
int f[N][N],k;
int abs(int aa)
{
if (aa>0) return aa;
return -aa;
}
int min(int aa,int bb)
{
if (aa>bb) return bb;
return aa;
}
int main()
{
scanf("%s",&u);
scanf("%s",&v);
scanf("%d",&k);
int u1=strlen(u),v1=strlen(v);
for (int i=0; i<u1; i++) f[i+1][0]=(i+1)*k;
for (int i=0; i<v1; i++) f[0][i+1]=(i+1)*k;
for (int i=1; i<=u1; i++)
for (int j=1; j<=v1; j++)
{
f[i][j]=min(f[i][j-1],f[i-1][j])+k;
f[i][j]=min(f[i][j],f[i-1][j-1]+abs(u[i-1]-v[j-1]));
}
printf("%d\n",f[u1][v1]);
return 0;
}
T4,村庄重建,题目大意:
B 地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。
给出 B 地区的村庄数 N,村庄编号从 0 到 N-1,和所有 M 条公路的长度,公路是双向的。并给出第 i 个村庄重建完成的时间 t[i],你可以认为是同时开始重建并在第 t[i]天重建完成,并且在当天即可通车。若 t[i]为 0 则说明地震未对此地区造成损坏,一开始就可以通车。之后有 Q 个询问(x, y, t),对于每个询问你要回答在第 t 天,从村庄 x 到村庄 y 的最短路径长度为多少。如果无法找到从 x 村庄到 y 村庄的路径,经过若干个已重建完成的村庄,或者村庄 x 或村庄 y 在第 t 天仍未重建完成 ,则需要返回-1。
ti为非负整数
保证了 t[0] ≤ t[1] ≤ „ ≤ t[N – 1]。
对于 30%的数据,有 N≤50;
对于 30%的数据,有 t[i] = 0,其中有 20%的数据有 t[i] = 0 且 N>50;
对于 50%的数据,有 Q≤100;
对于 100%的数据,有 N≤200,M≤N*(N-1)/2,Q≤50000,所有输入数据涉及整数均不超过 100000
题解:
因为t[i]递增且询问中的时间也是递增的,所以我们每次进行回答询问的时候,以被新解封的村庄为中点去做floyd即可,然后看村庄是否都解封,或者相通,然后判断输出
我一开始是错在f[i][i]=0,因为我忘了将自身跟自身设为0。。。
代码:
#include<iostream>
#include<cstdio>
#define INF 2333333
#define N 205
using namespace std;
int u,v,w,n,m,q,f[N][N],t[N];
int min(int aa,int bb)
{
if (aa>bb) return bb;
return aa;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=0; i<=n-1; i++)
{
for (int j=0; j<=n-1; j++) f[i][j]=INF;
f[i][i]=0;
}
for (int i=0; i<=n-1; i++) scanf("%d",&t[i]);
for (int i=1; i<=m; i++)
{
scanf("%d%d%d",&u,&v,&w);
f[u][v]=w;
f[v][u]=w;
}
int k=-1;
scanf("%d",&q);
for (int l=1; l<=q; l++)
{
scanf("%d%d%d",&u,&v,&w);
while (t[k+1]<=w && k<n-1)
{
k++;
for (int i=0; i<=n-1; i++)
for (int j=0; j<=n-1; j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
if (u>k || v>k || f[u][v]==INF) printf("%d\n",-1);
else printf("%d\n",f[u][v]);
}
return 0;
}