2016东莞市特长生考试

前传,本人真的是lalala,自己的代码竟然在同一个栏里编辑,保存的时候重新从硬盘读取,结果就,呵呵。

不过后面改了一下,大概是220pts,感觉自己还是很la。

 


一、子数整数
 
问题描述
对于一个五位数 a1a2a3a4a5,可将其拆分为三个子数:
sub1=a1a2a3
sub2=a2a3a4
sub3=a3a4a5
例如,五位数 20207 可以拆分成
sub1=202
sub2=020(=20)
sub3=207 现在给定一个正整数 K,要求你编程求出 10000(包括 10000)到 30000(包
括 30000)之间所有满足下述条件的五位数,条件是这些五位数的三个子数 sub1,
sub2,sub3 都可被 K 整除。
 
数据输入
从文件 num.in 输入,输入仅一行,为正整数 K(0<K<1000)。
 
数据输出
输出到文件 num.out,输出文件的每一行为一个满足条件的五位数,要求从
小到大输出。不得重复输出或遗漏。如果无解,则输出“-1”。
 
输入输出样例】num.in
15
num.out
22555
25555
28555
30000

就是一道简单的模拟题(这里就不讲思路了)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,f;
bool fj(int x)
{
    int n1=x/100,n2=x/10-(x/10000)*1000,n3=x%1000;
    if(n1%n==0&&n2%n==0&&n3%n==0) return true;
    return false;
}
int main()
{
    freopen("num.in","r",stdin);
    freopen("num.out","w",stdout);
    scanf("%d",&n);
    for(int i=10000;i<=30000;i++)
    {
        if(fj(i)) printf("%d\n",i),f=1;
    }
    if(!f) printf("-1");
    return 0;
} 

 

 


 

二、游戏问题
【问题描述】
“五四”青年节到了,某学校要举行一个游园活动,其中有一个这样的游戏:
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 号同学最后走到了第几号位置。
 
【数据输入】
- 2 - - 3 -
从文件 game.in 读入数据,输入共 1 行,包含 4 个整数 n、m、k、x,每
两个整数之间用一个空格隔开。
 
【数据输出】
结果输出到文件 game.out,输出共 1 行,包含 1 个整数,表示 10^k 轮
后 x 号小伙伴所在的位置编号。
 
【输入输出样例】
game.in
10 3 4 5
game.out
5
 
【数据说明】
对于 30%的数据, 0 < 𝑘 < 7;
对于 80%的数据, 0 < 𝑘 < 10^7;
对于 100%的数据, 1 < 𝑛 < 1,000,000,0 < 𝑚 < 𝑛 ,1 ≤ x ≤ n,0 < 𝑘 < 10^9。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
ll n, m, k, x;
ll power(ll a, ll b)
{
	ll Ans = 1;
	a %= n;
	while(b)
	{
		if(b & 1)Ans = Ans * a % n; 
		a = a * a % n;
		b >>= 1;
	}
	return Ans;
}
int main()
{
    freopen("game.in","r",stdin)
    freopen("game.out","w",stdout)
	scanf("%lld%lld%lld%lld", &n, &m, &k, &x);
	printf("%lld", (power(10, k) * m + x) % n);
	return 0;
}

思路:快速幂一下就好了。


三、字串距离
 
【问题描述】
设有字符串 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 的距离。
 
【数据输入】 - 4 -
从文件 blast.in 中读入数据,输入文件第一行为字符串 A ,第二行为字符串 B
A B 均由小写字母组成且长度均不超过 2000 。第三行为一个整数 K 1 K 100 ),
表示空格与其他字符的距离。
 
【数据输出】
输出到文件 blast.out 中,仅一行包含一个整数,表示所求得字符串 A B
距离。
 
【输入输出样例】
blast.in
cmc
snmn
2
blast.out
10
 
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
string s1,s2;
int k,len1,len2;
int f[4010][4010];
int min1(int a,int b,int c)
{
	return min(a,min(b,c));
} 
int main()
{
    //freopen("blast.in","r",stdin);
    //freopen("blast.out","w",stdout);
    cin>>s1>>s2;
    scanf("%d",&k);
    len1=s1.size(),len2=s2.size();
    for(int i=1;i<=len1;i++) f[i][0]=f[i-1][0]+k;
    for(int i=1;i<=len2;i++) f[0][i]=f[0][i-1]+k;
    for(int i=1;i<=len1;i++)
    for(int j=1;j<=len2;j++)
    	f[i][j]=min1(f[i-1][j-1]+abs(s1[i-1]-s2[j-1]),f[i-1][j]+k,f[i][j-1]+k);
    printf("%d",f[len1][len2]);
	return 0;
} 

四、村庄重建
 
【问题描述】
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。
 
【数据输入】
输入文件 rebuild.in 的第一行包含两个正整数 N,M,表示了村庄的数目与
公路的条数。
第二行包含 N 个非负整数 t[0], t[1], „, t[N – 1],表示了每个村庄重建完 成的时间,数据保证了 t[0] ≤ t[1] ≤ „ ≤ t[N – 1]。
接下来 M 行,每行 3 个非负整数 i, j, w,w 为不超过 10000 的正整数,表
示了有一条连接村庄 i 与村庄 j 的道路,长度为 w,保证 i≠j,且对于任意一对
村庄只会存在一条道路。
接下来一行也就是 M+3 行包含一个正整数 Q,表示 Q 个询问。
接下来 Q 行,每行 3 个非负整数 x, y, t,询问在第 t 天,从村庄 x 到村庄 y 的
最短路径长度为多少,数据保证了 t 是不下降的。
 
【数据输出】
输出文件 rebuild.out 包含 Q 行,对每一个询问(x, y, t)输出对应的答案,
即在第 t 天,从村庄 x 到村庄 y 的最短路径长度为多少。如果在第 t 天无法找到
从 x 村庄到 y 村庄的路径,经过若干个已重建完成的村庄,或者村庄 x 或村庄 y
在第 t 天仍未修复完成,则输出-1。
 
【输入输出样例】
rebuid.in
4 5
1 2 3 4
0 2 1
2 3 1
3 1 2
2 1 4
0 3 5
4
2 0 2
0 1 2
0 1 3
0 1 4
rebuid.out
-1
-1
5
4
【数据说明】
对于 30%的数据,有 N≤50;
- 5 - 对于 30%的数据,有 t[i] = 0,其中有 20%的数据有 t[i] = 0 且 N>50;
对于 50%的数据,有 Q≤100;
对于 100%的数据,有 N≤200,M≤N*(N-1)/2,Q≤50000,所有输入数据涉及整
数均不超过 100000。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n,m;
int r[201][201],top,len,q;
bool v1[201];
const int N=1e9;
struct str
{
	int w,id;
}v[201]; 
bool cmp(str a,str b)
{
	return a.w<b.w;
}
void update(int e)
{
   for(int i=0;i<=n-1;i++)
   for(int j=0;j<=n-1;j++)
   	 if(r[i][e]+r[e][j]<r[i][j]) r[i][j]=r[i][e]+r[e][j];
}
int main()
{
    freopen("rebuild.in","r",stdin);
    freopen("rebuild.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n-1;i++)
    for(int j=0;j<=n-1;j++) 
	r[i][j]=N;
	for(int i=1;i<=n;i++) scanf("%d",&v[i].w),v[i].id=i-1,r[i][i]=0;
    sort(v+1,v+n+1,cmp);
	for(int i=1,x,y,z;i<=m;i++)
	{
	  scanf("%d%d%d",&x,&y,&z);
	  r[x][y]=z,r[y][x]=z;
	}
	scanf("%d",&q);
	for(int i=1,x,y,t;i<=q;i++)
	{
		scanf("%d%d%d",&x,&y,&t);
		while(v[len+1].w<=t&&len<n) 
		{
		    ++len,v1[v[len].id]=1;
			update(v[len].id);
		}
		if(v1[x]&&v1[y]&&r[x][y]!=N) printf("%d\n",r[x][y]);
		else printf("-1\n");
	} 
	return 0;
} 

思路:由于提问时间严格递增的,所以我们可以一个点一个点插入去做,然后再加上路是否可以走通的判断就可以了,总共加起来其实就做了一次floyd。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值