您的位置:首页 > 其它

2018年新生个人训练赛第十一场(第27届宁波市信息学竞赛小学组,初中组)

2018-03-08 16:50 573 查看
这次训练赛有好几个坑,其中猜数字我真的不会做。都是在网上找来的代码。其中含义还希望读者能自己琢磨吧!(自身现在也是一知半解,至于怎么出来的想法望各位大牛能提点提点)。


问题 A: 傻瓜电梯

时间限制: 1 Sec  内存限制: 128 MB
提交: 174  解决: 25

[提交][状态][讨论版]


题目描述

所谓傻瓜电梯指的是在响应用户请求时缺乏相应的“智商”,在上升或下降的过程中不 能把中途的乘客捎带入电梯,而只会严格按照用户发出请求的先后顺序依次完成任务。
比如,原来电梯在 1 楼,首先 6 楼有一位乘客发出请求,要求由 6 楼乘坐到 10 楼去,此时电梯马上会上去,但在电梯上升到 3 楼时,另外一位乘客请求由 5 楼乘坐到 8 楼去,傻瓜电梯却不会在上升途中把 5 楼的乘客捎带上去,而只会先把 6 楼的乘客送到 10 楼,然后 再下来把 5 楼的乘客送到 8 楼。
傻瓜电梯由 i 楼上升到 i+1 楼(或下降到 i-1 楼)的时间都是 3 秒,每到达一个楼层, 不管进出乘客有多少,也不管乘客只有进、只有出或者进出电梯都有,所耽搁的时间都是 6 秒。现在味味要根据傻瓜电梯接受到的 n 个用户请求,编程计算傻瓜电梯把所有乘客送到目 标楼层时总共所需要的时间。
如果某批乘客到达目标楼层后,电梯没有马上要响应的请求,则电梯在前一批乘客的 目的地等待,这个等待时间也需计入总花费时间。直到下一批乘客发出新请求,电梯才会从 当前位置出发,前往下一批乘客的出发楼层。


输入

输入第一行包含两个整数 x(1<=x<=100)和 n(1<=n<=100),分别表示 傻瓜电梯开始所在的楼层和总共接收到的请求数目。下面有 n 行,每行包含 3 个整数,依次 表示该请求发出的时间、乘客目前所在的楼层和将要去的目标楼层。其中请求发出的时间以 秒为时刻单位,最大可能的值是 2000。如果某两个请求的发出时间相同,则按照输入中原始的先后顺序依次处理。


输出

输出只包含一行一个整数,表示傻瓜电梯把所有乘客送到目标楼层后总共所需要的时间(从得到第一条请求时开始计算时间),单位是秒。


样例输入

3 4
10 10 2
18 1 9
2 1 12
8 6 10


样例输出

162


提示

第一批乘客发出请求到离开电梯所需时间:3*2+6+3*11+6=51 从前一批乘客离开电梯到第二批乘客离开电梯所需时间:3*6+6+3*4+6=42 第三批乘客从出发地出发到离开电梯所需时间:

3*8+6=30(由于出发地与前一批乘客目的地相同,所以上下客时间不必再加 6) 从前一批乘客离开电梯到第四批乘客离开电梯所需时间:3+6+3*8+6=39 总花费时间:51+42+30+39=162
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef struct point{
int num,t,s,f;
}p;
p a[110];
int cmp(p x,p y){
return x.t<y.t;
}
int main()
{
int x,n,c=3,ans=0,time=2020;
scanf("%d%d",&x,&n);
for(int i=0;i<n;i++){
scanf("%d%d%d",&a[i].t,&a[i].s,&a[i].f);
a[i].num=i;
time=min(time,a[i].t);
}

sort(a,a+n,cmp);

ans=0;
ans=ans+abs(a[0].s-x)*3;
ans+=6;
ans=ans+abs(a[0].f-a[0].s)*3;
if(a[0].f!=a[1].s){
ans+=6;
}
for(int i=1;i<n;i++){
ans=max(a[i].t,ans);
ans=ans+abs(a[i-1].f-a[i].s)*3;
if(a[i-1].f!=a[i].s){
ans+=6;
}
ans=ans+abs(a[i].s-a[i].f)*3;
if(a[i].f!=a[i].s){
ans+=6;
}
}
printf("%d\n",ans);
return 0;
}



问题 B: 数字替换

时间限制: 1 Sec  内存限制: 128 MB
提交: 172  解决: 46[提交][状态][讨论版]


题目描述

味味很喜欢玩一个数字替换的游戏,数字替换游戏是这样的:给出一个 n 位正整数 a, 然后再给你一个长度为 m 的数字序列 b,味味可以用 b 中的一些数字与 a 中各个位置上的 数字进行一对一的交换(当然也可以选择不交换)。当然 b 中的每个位置上的数字最多只能 被使用一次。这个游戏的目的是经过一系列替换后,使 a 的数值达到最大。
味味很聪明,在位数不多的情况下,总能快速的求出最后 a 的最大数值,但是当 n 很 大时,味味就无能为力了,所以她希望会写程序的你帮助她快速的求解 a 最后能到达的那 个最大值。


输入

输入共包含三行。第一行两个用空格隔开的正整数 n,m。第二行一个正整数 a(a 的最高位必定不是 0)。第三行一个长度为 m 的数字序列 b。


输出

输出仅包含一行一个数值,表示 a 最大可能达到的数值(输出不能含前导0)。


样例输入

4 3
1024
010


样例输出

1124


提示

b 中的一个 1 和 a 中的第二位上的 0 进行交换。

对于 20%的数据 1≤n,m≤10 

对于 50%的数据 1≤n,m≤2000 

对于 100%的数据 1≤n,m≤100000

贪心便可。。。

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int str[11]={0},n,m;
char a[100050],b[100050];
scanf("%d %d\n",&n,&m);
scanf("%s",a);
scanf("%s",b);
for(int i=0;i<m;i++){
str[b[i]-'0']++;
}
for(int i=0;i<n;i++){
for(int j=9;j>=0;j--){
if(a[i]<(j+'0')&&str[j]){
a[i]=(j+'0');
str[j]--;
break;
}
}
}
printf("%s\n",a);
return 0;
}



问题 C: 取珠子

时间限制: 1 Sec  内存限制: 128 MB
提交: 150  解决: 23
[提交][状态][讨论版]


题目描述

味味妈妈有一串珠子串成的项链,这个项链中的珠子最多有 3 种颜色(红、蓝、白, 分别用 r、b、w 表示)。某天,味味想从妈妈项链中取出一些珠子来玩,妈妈虽然答应了, 但提出了以下条件:
(1)只能在项链中选择一个地方剪断,然后从断开的两端开始依次取出珠子;
(2)每一端取珠子时,如果珠子颜色与该端第一颗珠子颜色相同则可以连续取下去, 直到出现一颗与该端第一颗颜色不同的珠子。如果遇到白色珠子则可根据需要看做蓝色或者 红色。


 
味味对于颜色并没有特殊要求,但她想得到尽可能多的珠子。
为方便表示,我们给项链中的珠子按顺时针方向编号,如图-1 和图-2 所示为两种可能的项链情况(珠子都有 11 颗)。
对于图-1 来说,如果在 1 和 2 号珠子之间剪断,则味味可以取到共 2 颗珠子。而如果 在 6 和 7 号珠子之间剪断,则味味可以取到共 5 颗珠子(左边取 3 颗红色 r,右边取 2 颗 蓝色 b),而 5 颗珠子也是味味从这串项链中最多可以取到的珠子数量。
对于图-2 中的项链来说,如果在 1 和 2 号珠子之间剪断,则共可取走 4 颗珠子(将 1 号珠子当做蓝色,这样左边可取 3 颗,右边可取 1 颗蓝色 b)。而如果在 2 和 3 号之间剪断, 则共可取走 6 颗珠子(将 1 号珠子当做蓝色,这样左边可取 4 颗蓝色 b,右边可取 2 颗红 色 r)。


输入

输入共包含二行。第一行一个整数 n,表示项链中珠子的总数。第二行为 一串长度为 n 的字符,由字符 r,b,w 组成。表示项链从某个珠子开始按顺时针方向展开 的珠子排列情况(当然,这个珠子并不一定是味味实际需要剪断的位置)。


输出

输出仅包含一行一个数值,表示按照妈妈的规则,味味最多能得到的珠子数量。


样例输入

11
wbrrbbwbrbb


样例输出

6


提示

将 1 号珠子看成蓝色,则在 2 和 3 号珠子之间剪断,味味可得到的 6 颗珠子编号分别为1、2、3、4、10、11;也可在 4 和 5 号珠子间剪断,将 7 号珠子看成蓝色,则味味可得到珠子的编号为 3、4、5、6、7、8。

对于 60%的数据 3≤n≤100

对于 100%的数据 3≤n≤350

取珠子,把它复制三遍即可。

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int n,ans=0;
char a[10000];
scanf("%d",&n);
scanf("%s",a);
for(int i=0;i<n;i++){
a[i+n]=a[i];
a[i+2*n]=a[i];
}a[n*3]='\0';
for(int i=n;i<=2*n;i++){
char ch1=a[i],ch2=a[i+1];
int l=1,r=1;
for(int j=i-1;j>=0;j--){
if(a[j]=='w'){
l++;
}else if(ch1==a[j]){
l++;
}else{
if(ch1=='w'){
ch1=a[j];
l++;
}else{
break;
}
}
}
for(int j=i+2;j<=3*n;j++){
if(a[j]=='w'){
r++;
}else if(ch2==a[j]){
r++;
}else{
if(ch2=='w'){
r++;
ch2=a[j];
}else{
break;
}
}
}
ans=max(r+l,ans);
}
ans=min(ans,n);
printf("%d\n",ans);
return 0;
}



问题 D: 猜数字

时间限制: 1 Sec  内存限制: 128 MB
提交: 8  解决: 3
[提交][状态][讨论版]


题目描述

味味最近在玩猜数字的游戏,现在她也希望你来玩一下这个游戏。猜数字游戏的规则是这样的,告诉你一个正整数 n(2<=n<=11),然后味味心中会想一个 n 个数字组成的数字串(数字串最前面若干位可能是 0)。味味会随意排列 n 位数上的数字,这样可能产生 n!个 n位数。(n!=1×2×3×4×5×……×n,n!念作“n 阶乘”). 比如味味想了一个三位数 abc,那么一共会产生六个三位数,分别为 abc,acb,bac,bca,cab,cba
然后味味会把这 n!个 n 位数求和得到 S(若某数第一位开始有若干个 0,则求和时这 些 0 舍去。如有数“0123”,则求和时加到 s 中的值是 123),她会告诉你总和 S 减去她心 中想的那个数的值,请你猜出味味心中想的那个数。


输入

输入共包含两行。第一行一个整数 n(含义如前面所述),第二行一个正整数 S,表示 n!个数的总和减去味味心中那个数的值。


输出

输出共一行一个数,表示味味心中想的那个n位数(测试数据保证存在唯一解)。如果该数第一位开始有若干个0,则输出时这些0也必须输出。


样例输入

2
90


样例输出

09


提示

如果味味心中想的是 09,则 S=09+90-09=9+90-9=90,符合要求。

对于 20%的数据 n≤3
对于 60%的数据 n≤5

对于 100%的数据 2≤n≤11  ,0≤S≤1018

这题真的不会,都是找来别人的代码(因为落下一题总觉得不怎么好)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
long long tmp[20];
long long first[20];
long long remain;
int n;
void init()
{
tmp[1]=1;
for (int i=2; i<=12; ++i)
tmp[i]=tmp[i-1]*10+1;
cin >> n;
cin >> remain;
for (int i=0; i<=9; ++i)
first[i]=i*tmp
;
}
void print(long long x,long long y,long long z)
{
for (int i=1; i<=n-1; ++i)
y*=i;
long long k1=0,k2=1;
for (int i=1; i<=n; ++i)
{
k1+=k2*y;
k2*=10;
}
if (k1-x!=remain) return;
int c[20];
int pos=0;
memset(c,0,sizeof(c));
while (x>0)
{
c[pos++]=x%10;
x/=10;
}
for (int i=n-1; i>=0; --i)
cout << c[i];
cout << endl;
exit(0);
}
void solve()
{
int ll=1;
for (int i=1; i<=n-1; ++i) ll*=i;
for (int i=0; i<=n*9; ++i)
{
for (int j=0; j<=9; ++j)
{
long long second=first[j]*i*ll;
long long third=second-remain;
long long w = third;
int x=0;
while (w>0)
{
x+=w%10;
w/=10;
}
if (x==i && third>0) print(third,i,j);
}
}
}
int main()
{
init();
solve();
}



问题 E: 扫雷I

时间限制: 1 Sec  内存限制: 128 MB
提交: 119  解决: 39

[提交][状态][讨论版]


题目描述

Windows 中的扫雷游戏是大家都熟悉的小游戏,今天,味味也设计了一个简易的扫雷游戏。味 味设计的扫雷游戏功能如下:
1.程序一开始会读入扫雷区域大小 n,表示游戏区域有 n*n 个小方格组成,接下来会读入 n 行 信息,每行有 n 个整数(每个整数可能是 0,也可能是 1),每两个整数之间用一个空格分隔。其中 0 所在位置表示该小方格内没有地雷,1 所在位置表示该小方格内有地雷(游戏开始时,扫雷区域 中必定包含至少一个地雷)。 
接下来每行输入两个用空格分开的正整数 i 和 j,每一行的一对 i 和 j 表示用户用鼠标单击扫 雷区域中第 i 行第 j 列位置上的小方格(就象我们使用 Windows 中扫雷游戏一样),i 和 j 表示的 位置必定在扫雷区域内。程序每输入一对 i 和 j,就马上进行相应的处理(就象我们在 Windows 中 鼠标单击某个小方块就会出现结果一样)。 
2.程序将根据读入的一组 i 和 j 的值来对扫雷区域作相应处理,具体的处理规则如下: 
(1)如果 i 和 j 表示的小方格内没有地雷、而且也没有被处理过(就是第 i 行第 j 列的数值 是 0),那么将以该小方格为中心的一个正方形区域内所有没有地雷的小方格都赋值为-1(表示该 区域的地砖已经被掀开了)。如果在当前正方形区域内有一个位置号为 i1 和 j1(注意:i1<>i 并且 j1<>j)的小方格内恰好有地雷,则此地雷就被顺利扫除,将该位置标记为-2。如果该正方形区域 内某些小方格已经被处理过,则对这些小方格不再做任何处理。 
举个例子来说明一下,假如输入信息如下左边所示,那么处理结果就如下右边所示: 



(2)如果 i 和 j 表示的小方格已经被处理过(就是第 i 行第 j 列的数值是-1 或者是-2),那 么不作任何处理,继续去读取下一行的 i 和 j 的值。 
(3)如果 i 和 j 表示的小方格刚好有地雷,并且该小方格没有被处理过(就是第 i 行第 j 列
的数值是 1),那么表示用户触雷,马上输出信息“GAME  OVER!”,程序结束。 
3.如果在读入 i 和 j 的过程中一直没有触雷,那么就一直按照位置信息处理下去,直到满足下 列条件之一,就输出相应信息并结束程序: 
(1)读入的 i 和 j 的值都是 0(表示用户不再在某个小方格内单击鼠标右键了),则输出处理 后整个扫雷区域的状态(就是输出 n 行 n 列的方阵,每行中两个整数之间用一个空格分隔,末尾没 有多余空格),然后程序结束。 
(2)如果某次处理完后,游戏区域内所有的地雷都被扫除了,那么不必再读入下一行的信息, 输出信息“YOU ARE WINNER!”,程序结束。 


输入

输入第一行一个整数 n(n<=50),接下来是一个 n*n 的方阵。再接下来是若干行,每行空格分隔的两个整数,表示 i 和 j,以 0 0 结束。 


输出

输出包含一行,可能输出“YOU ARE WINNER!”,可能输出“GAME OVER!”,
也可能输出一个处理后的方阵。 


样例输入

60 0 0 0 0 0
0 0 1 0 0 0
1 0 0 0 1 0
0 0 0 0 0 0
0 1 0 0 0 1
0 0 0 0 0 0
1 1
3 45 5
4 62 30 0


样例输出

-1 -1 0 0 0 0
-1 -1 -2 -1 -1 0
1 0 -1 -1 -2 0
0 0 -1 -1 -1 -1
0 1 0 -1 -1 -2
0 0 0 -1 -1 -1


模拟即可。
#include<stdio.h>
#include<string.h>
int G[55][55],a[55][55],vis[55][55],flag=1,cnt1,cnt2,n;
void tu(int x,int y){
if(x<=0||x>n||y<=0||y>n){
return ;
}
if(vis[x][y]==0&&a[x][y]==1){
vis[x][y]=1;
cnt2++;
}
if(a[x][y]==1){
G[x][y]=-2;
}else{
G[x][y]=-1;
}
}
int check(int x,int y){
int ans=0;
for(int i=x-1;i<=x+1;i++){
for(int j=y-1;j<=y+1;j++){
tu(i,j);
}
}
}
int ck(int x,int y){
if(a[x][y]==1){
return 0;
}else if(a[x][y]==0&&G[x][y]==0)
check(x,y);
else{
return 1;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
if(a[i][j]==1){
cnt1++;
}
}
}
int tx,ty;
while(~scanf("%d%d",&tx,&ty),(tx||ty)){
if(G[tx][ty]==-1||G[tx][ty]==-2){
continue;
}
if(ck(tx,ty)==0){
printf("GAME OVER!\n");
return 0;
}
if(cnt2==cnt1){
printf("YOU ARE WINNER!\n");
return 0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(G[i][j]==0&&a[i][j]==1){
G[i][j]=1;
}
printf("%d%c",G[i][j],j==n?'\n':' ');
}
}
return 0;
}



问题 F: 无根树

时间限制: 1 Sec  内存限制: 128 MB
提交: 10  解决: 9

[提交][状态][讨论版]


题目描述

味味最近对树很感兴趣,什么是树呢?树就是有n个点和n-1条边形成的无环连通无向图。
今年2012年浙江省队选拔赛中味味发现了一个树中最长链(就是树当中距离最远的点对)试题,于是她着手对树进行了一些研究和思考。
味味在研究过程中想知道,对于一个无根树,当节点i作为根的时候树的高是多少。所谓树高指的是从根节点出发,到离根节点最远叶子节点所经过的节点的总数,详见输入输出样例。
味味现在遇到了一些烦心的事情,不想再继续思考了,请你帮助她解决这个问题。


输入

输入共N行。第一行为一个正整数N,表示树的节点个数。第2行到第N行里,每行两个用空格隔开的正整数a和b,表示a与b有连边。


输出

输出共N行,第i行表示以节点i为根时的树高。


样例输入

3
1 2
2 3


样例输出

3
2
3


提示

节点1为根时,树的形态如下,此时树高为3。



节点2为根时,树的形态如下,此时树高为2。节点3为根时树的形态同于节点1为根情形。



对于30%的数据有N≤100。

对于60%的数据有N≤300。

对于100%的数据有1≤N≤1000,1≤a,b≤N

#include<bits/stdc++.h>
using namespace std;
int n,g[2000],tot,depth[2000],MAX;
struct tree{
int t,next;
}e[500000];
void addedge(int a,int b){
e[++tot].t=b;
e[tot].next=g[a];
g[a]=tot;
}
void dfs(int x,int father){
depth[x]=depth[father]+1;
MAX=max(MAX,depth[x]);
for(int i=g[x];i;i=e[i].next){
if(e[i].t!=father){
dfs(e[i].t,x);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
for(int i=1;i<=n;i++){
MAX=0;
dfs(i,0);
printf("%d\n",MAX);
memset(depth,0,sizeof(depth));
}
return 0;
}



问题 G: 积木

时间限制: 1 Sec  内存限制: 128 MB
提交: 51  解决: 10

[提交][状态][讨论版]


题目描述

味味有一个 A×B×C 的长方体积木,积木是有 1×1×1 的小积木块组成的。我们设定这个长 方体的高为 A,宽为 B,长为 C。(为方便起见,长方体的长不一定要比宽的数值大)。
现在味味在这个长方体中的的左上角挖去了一个(A-1)×(B-2)×(C-2)的小长方体。并且告诉你 被挖去长方体的体积为 n,即 n=(A-1)×(B-2)×(C-2)。现在问你,被挖去小长方体后,原有长方体 积木中剩下的 1×1×1 的小积木块最少和最多分别是多少个。也就是说,在告诉你 n 值的前提下, 求 min{A×B×C-n}和 max{A×B×C-n}。


输入

输入共1行,仅一个正整数n。


输出

输出共1行包含两个用空格隔开的正整数,依次表示最少剩余小积木块和最多剩余小积木块个数。


样例输入

4


样例输出

28 41


提示

4=(2-1)×(4-2)×(4-2) 最少剩余的小积木块为 2×4×4-4=28(此时 A,B,C 值分别为 2,4,4)

4=(5-1)×(3-2)×(3-2) 最多剩余的小积木块为 5×3×3-4=41(此时 A,B,C 值分别为 5,3,3)

对于 20%的数据 1 ≤n≤400

对于 50%的数据 1 ≤n≤106对于 100%的数据 1 ≤ n≤109
暴力出奇迹。

#include<stdio.h>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
int main()
{
ll n,cnt=0;
scanf("%lld",&n);
ll a[100000];
for(int i=1;i*i<=n;i++){
if(n%i==0){
a[cnt++]=i;
a[cnt++]=n/i;
}
}sort(a,a+cnt);
map<ll,ll>my;
for(int i=0;i<cnt;i++){
my[a[i]]=1;
}
ll ans1=0x3f3f3f3f,ans2=-1;

for(int i=0;i<cnt;i++){
if((n%a[i]==0)&&(my[n/a[i]]==1))
for(int j=0;j<cnt;j++){
if(((n/a[i])%a[j]==0)&&(my[(n/a[i])/a[j]]==1))
for(int k=0;k<cnt;k++){
if(a[i]*a[j]*a[k]==n){
ans1=min((a[i]+1)*(a[j]+2)*(a[k]+2)-n,ans1);
ans2=max((a[i]+1)*(a[j]+2)*(a[k]+2)-n,ans2);
}
}
}
}
printf("%lld %lld\n",ans1,ans2);
return 0;
}



问题 H: 幸运数III

时间限制: 1 Sec  内存限制: 128 MB
提交: 75  解决: 16[提交][状态][讨论版]


题目描述

4 和 7 是味味的幸运数字。幸运数是那些只由幸运数字组成的正整数。如 47,477 是幸运数,而 5,17,417 就不是幸运数。
定义 next(x)为大于或等于 x 的最小的幸运数。
味味对以下表达式的值很感兴趣 :
next(L)+next(L+1)+...+next(R-1)+next(R)。
现在告诉你 L 和 R 的值,希望你能帮助味味计算出这个表达式的值。


输入

输入仅一行包含两个正整数 L 和 R(1≤L≤R≤109 ),L 和 R 的值之间用一个空格分隔。


输出

输出只有一行一个整数,表示表达式的值。


样例输入

2 7


样例输出

33


提示

next(2)+next(3)+next(4)+next(5)+next(6)+next(7)=4+4+4+7+7+7=33对于 20%的数据,1≤L≤R≤1000

对于 40%的数据,1≤L≤R≤106另有 20%的数据,L=R

对于 100%的数据,1≤L≤R≤109
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll luck[10000];
int cnt;
int a[2]={4,7};
typedef struct point{
ll x,step;
}p;
void bfs(){
queue<p>q;
p first={0,0};
q.push(first);
while(!q.empty()){
p cur=q.front();
q.pop();
p next;
if(cur.step==11){
return ;
}
for(int i=0;i<2;i++){
next.x=cur.x*10+a[i];
next.step=cur.step+1;
q.push(next);
luck[++cnt]=next.x;
}
}
}
int main()
{
bfs();
ll L,R,ans=0;
int k=0;
scanf("%lld %lld",&L,&R);
for(int i=0;i<=1024;i++){
if(luck[i]>=L){
k=i;break;
}
}
for(int i=L;i<=R;i++){
if(i>luck[k]){
k++;
}
ans+=luck[k];

}
printf("%lld\n",ans);

return 0;
}



问题 I: Clothes

时间限制: 2 Sec  内存限制: 256 MB
提交: 187  解决: 37

[提交][状态][讨论版]


题目描述

A little boy Gerald entered a clothes shop and found out something very unpleasant: not all clothes turns out to match. For example, Gerald noticed that he looks rather ridiculous in a smoking suit and a baseball cap.

Overall the shop sells n clothing items, and exactly m pairs of clothing items match. Each item has its price, represented by an integer number of rubles. Gerald wants to buy three clothing items so that they matched each other.
Besides, he wants to spend as little money as possible. Find the least possible sum he can spend.


输入

The first input file line contains integers n and m — the total number of clothing items in the shop and the total number of matching pairs of clothing items (3≤n≤100,0≤m≤n(n-1)/2).

Next line contains n integers ai (1≤ai≤106) — the prices of the clothing items in rubles.

Next m lines each contain a pair of space-separated integers ui and vi (1≤ui,vi≤n,ui≠vi). Each such pair of numbers means that the ui-th and the vi-th clothing items match each other. It is guaranteed that in each pair ui and vi
are distinct and all the unordered pairs (ui,vi) are different.


输出

Print the only number — the least possible sum in rubles that Gerald will have to pay in the shop. If the shop has no three clothing items that would match each other, print "-1" (without the quotes).


样例输入

3 31 2 3
1 2
2 33 1


样例输出

6


提示

In the first test there only are three pieces of clothing and they all match each other. Thus, there is only one way — to buy the 3 pieces of clothing; in this case he spends 6 roubles.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll n,m,price[1100];

int main()
{
ll ans=99999999;
int G[110][110]={0},l,r;
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&price[i]);
}for(int i=1;i<=m;i++){
scanf("%d%d",&l,&r);
G[l][r]=G[r][l]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(G[i][j]+G[i][k]+G[k][j]==3){
ans=min(ans,price[i]+price[j]+price[k]);
}
}
}
}

if(ans==99999999){
printf("-1\n");
}else{
printf("%lld\n",ans);
}return 0;
}



问题 J: Sum of Digits

时间限制: 2 Sec  内存限制: 256 MB
提交: 98  解决: 46[提交][状态][讨论版]


题目描述

Having watched the last Harry Potter film, little Gerald also decided to practice magic. He found in his father's magical book a spell that turns any number in the sum of its digits. At the moment Gerald learned that, he came across
a number n. How many times can Gerald put a spell on it until the number becomes one-digit?


输入

The first line contains the only integer n (0≤n≤10100000). It is guaranteed that n doesn't contain any leading zeroes.


输出

Print the number of times a number can be replaced by the sum of its digits until it only contains one digit.


样例输入

991


样例输出

3


提示

The test contains number 991. As one casts a spell the following transformations take place: 991 → 19 → 10 → 1. After three transformations the number becomes one-digit.

#include<stdio.h>
#include<string.h>
typedef long long ll;
int main()
{
char str[1005000],a[1000002];
scanf("%s",str);
ll t=0,ans=1;
int len=strlen(str);
for(int i=0;i<len;i++){
t+=(str[i]-'0');
}
if(t<10&&len<2){
printf("0");
return 0;
}
for(;;){
if(t<10){
printf("%lld\n",ans);
break;
}
ans++;
sprintf(a,"%lld",t);
//printf("%s\n",a);
t=0,len=strlen(a);
for(int i=0;i<len;i++){
t+=(a[i]-'0');
}

}
return 0;
}

#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;

char str[1000000];

int f(int p) {
return (p == 0) ? 0 : (p%10 + f(p/10));
}

int main(void) {
scanf("%s", str);
if (strlen(str) == 1) {
printf("0\n");
return 0;
}
int cnt = 0;
for (char *i = str; *i; i++) {
cnt += (*i - '0');
}
int res = 1;
while (cnt >= 10) {
cnt = f(cnt);
++res;
}
printf("%d\n", res);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: