练习赛7-补题

A - Display The Number

有一个大的电子屏幕,可以显示998244353个十进制数字。数字的显示方式与不同的电子闹钟相同:每个数字的位置由7个部分组成,可以打开和关闭,组成不同的数字。下图描述了如何显示所有10位小数:

可以看到,不同的数字可能需要打开不同数量的段。例如,如果你想显示1,你必须打开屏幕的2段,如果你想显示8,显示数字的某个地方的所有7段都应该打开。

您希望在屏幕上显示一个非常大的整数。不幸的是,屏幕出BUG了:不能同时打开超过n个片段。所以现在你想知道什么是最大的整数可以显示通过打开不超过n段。你的程序应该能够处理t个不同的测试用例。

输入

第一行包含一个整数t(1≤t≤100)——输入的测试用例的数量。

接来是测试用例,每一行包含一个整数n(2≤n≤1e5),表示在相应的测试用例中可以打开的最大段数。

它保证输入中所有测试用例的n的总和不超过1e5。

输出

对于每个样例,输出能显示的最大数字

注意哦,这个数字可能是很大的哦

输入

2
3
4

输出

7
11

题目大意及解题思路 :

用有限的段输出能显示的最大数字。

 如输入2时显示1, 3时显示7, 1和7两个数字是性价比最高的.只需要判断这个数字是奇数还是偶数, 是偶数就全输出1, 奇数输出1个7, 随后的都输出1即可。

#include<stdio.h>
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, x;
		scanf("%d",&n);
		if (n % 2 == 0){
			x = n / 2;
			while (x--){
				printf("1");
			}
		}
		else {
			printf("7");
			x = (n - 3) / 2;
			while (x--){
				printf("1");
			}
		}
		printf("\n");
	}
	return 0;
}

B - Minimize the Permutation

给定一个长度为n的数组,数组由1到n的任意顺序的n个不同整数组成(这n个数保证不重复),对于给定的数列,最多可以执行n-1个操作(可能根本不执行任何操作)。第i种操作允许交换i和i+1两个位置的值。每种操作最多只能执行一次。操作可以按任意顺序执行。你的任务是通过按一定顺序执行某些给定操作找到最小字典序的数列. 例如,让我们考虑数列[5,4,1,3,2]。我们能得到的最小数列是[1,5,2,4,3],我们可以用以下方法来做:

  • 执行第二种操作(交换第二和第三个元素)并获得数列[5,1,4,3,2];
  • 执行第四种操作(交换第四个和第五个元素)并获得数列[5,1,4,2,3];
  • 执行第三种操作(交换第三个和第四个元素)并获得数列[5,1,2,4,3]。
  • 执行第一种操作(交换第一个和第二个元素)并获得数列[1,5,2,4,3];
  • 另一个例子是[1,2,4,3]。通过执行第三种操作(交换第三和第四个元素),我们可以获得的最小可能置换是[1,2,3,4]。

Input

第一行输入一个t,代表以下有t组数据(1≤t≤100)

每组数据的第一行给一个n代表接下来输入一个大小为n的数列.(1≤n≤100)

每组数据的第二行给定这个数列每一位的数字 ai

Output

对于每一组数据,输出他能得到的最小字典序数列

Input

4
5
5 4 1 3 2
4
1 2 4 3
1
1
4
4 3 2 1

Output

1 5 2 4 3 
1 2 3 4 
1 
1 4 3 2 

 题目大意及解题思路:

给你n个数的序列(1~n)。有n-1种操作,操作n-1就是把a[n-1]与a[n]交换位置。每种操作至多只能使用一次。求字典序最小排列。

找到最小值,将最小值放置在前面,然后就不动原本最小值以及前面的位置。然后和之前一样,找后面的最小值,在依次放在前面就行。

代码实现:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,x;
		cin>>n;
		int a[n],b[n]={0};//b[]用来标记当前位置是否与后一位进行交换
		for(int i=0;i<n;i++){
		cin>>a[i];
		}
		for(int i=n-2;i>=0;i--){//从最后一位开始向前遍历 
			for(int j=i;j<n-1;j++){//从i开始往后找可以交换的一对元素
				if(a[j]>a[j+1] && b[j]==0){
					swap(a[j],a[j+1]);//交换 
					b[j]=1;
				}
			}
		}
		for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
		}
		cout<<endl;
	}
}

C - Two Rabbits

一条数轴,上面有两只兔子。 一只兔子位于 x 坐标,每秒跳 a 个单位,另一只位于 y 坐标,每秒跳 b 个单位,保证 x<y ,两只兔子相向而行。 请你求出两只兔子是否会在整数秒相遇,如果是,打印出相遇的那一秒(初始时间从 0 开始),如果无法在整数秒相遇,则输出 -1 。

Input

第一行一个数 t 表示数据组数 1 <= t <= 1000

接下来t行每行四个数x,y,a,b(0<=x<y<=10^9, 1<=a, b<=10^9)

Output

对于每行输出一个数表示答案

Input

5
0 10 2 3
0 10 3 3
900000000 1000000000 1 9999999
1 2 1 1
1 3 1 1

Output

2
-1
10
-1
1

 题目大意及解题思路:

一只兔子位于 x 坐标,每秒跳 a 个单位,另一只位于 y 坐标,每秒跳 b 个单位,求出两只兔子是否会在整数秒相遇。

两兔相距 y-x;每秒可跳a+b单位,我们只需要判断(y-x)%(a+b)是否整除即可。

代码实现:

#include<stdio.h>
#include<math.h>
int main(){
	int x, y, a, b, n;
	scanf("%d", &n);
	for (int i = 0; i<n; i++){
		scanf("%d %d %d %d", &x, &y, &a, &b);
		if ((y - x) % (a + b) == 0){
			printf("%d\n", (y - x) / (a + b));
		}
		else{
			printf("-1\n");
		}
	}
	return 0;
}

D - 吃糖果

zjl姐姐终于买好了女装,但是zjl姐姐穿衣服有个特殊的癖好,就是不喜欢连着两天穿同一款女装,喜欢先穿一款,再穿另一款(同一款女装可以有多件,别问上一题为什么只有一件,zjl姐姐的心思就是这么反复无常)。可是zjl姐姐不知道是否存在一种穿女装的顺序使得他把所有的女装全都穿完,请你写个程序帮忙计算一下。

Input

第一行有一个整数T,接下来T组数据,每组数据占2行,第一行是一个整数N(0<N<=1000000),第二行是N个数,表示N款女装的数目Mi(0<Mi<=1000000)。
 

Output

对于每组数据,输出一行,包含一个"Yes"或者"No"。
 

Sample Input

2
3
4 1 1
5
5 4 3 2 1

Sample Output

No
Yes

题目大意及解题思路:

 这是一道排列问题,就是将若干种类的女装按要求排列,相同种类的女装不能相邻。

我们可以先找到数量最多的一种女装先排好,那么它中间会有max-1个空需要别的种类女装插进去,如果除去数量最多的哪一款女装后剩下的女装种类小于这max-1个空,则说明肯定会出现重复排列

代码实现:

#include<stdio.h>
int main() {
	long long t;
	scanf("%lld",&t);
	while(t--) {
		long long max = 0, sum = 0;
		long long n;
		scanf("%lld",&n);
		while(n--) {
			long long x;
			scanf("%lld",&x);
			if(x > max) max = x;
			sum += x;
		}
		if(sum-max < max-1)
		printf("No\n");
		else printf("Yes\n");
	}
	return 0;
}

E - Reading comprehension

 

Read the program below carefully then answer the question.
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>

const int MAX=100000*2;
const int INF=1e9;

int main()
{
  int n,m,ans,i;
  while(scanf("%d%d",&n,&m)!=EOF)
  {
    ans=0;
    for(i=1;i<=n;i++)
    {
      if(i&1)ans=(ans*2+1)%m;
      else ans=ans*2%m;
    }
    printf("%d\n",ans);
  }
  return 0;
}

Input

Multi test cases,each line will contain two integers n and m. Process to end of file.
[Technical Specification]
1<=n, m <= 1000000000

Output

For each case,output an integer,represents the output of above program.

Sample Input

1 10
3 100

Sample Output

1
5

题目大意及解题思路:

初始的ans = 0,给出 n, m。从1-n,如果 i 为奇数,ans = (ans * 2 + 1) % m,如果i为偶数,ans = ans * 2 % m
如果我们只计算 偶数项 那么递推公式就是ans[n] = 4 * ans[n - 2] + 2

如果 n 是偶数 那么刚好 就按这个公式推 第 n / 2 项
如果 n 是奇数 那么就是 第 【 n / 2 项 】 * 2 + 1项

可以得出公式:(a/b)%c=(a%bc)/b;(a-b)%c=(a%c-b%c)

代码实现:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
long long poww(ll a,ll b,ll c){
    long long ans=1;
    a=a%c;
    while(b!=0){
        if(b&1) ans=(ans*a)%c;
        b>>=1;
        a=(a*a)%c;
    }
    return ans;
}
int main()
{   ll n,m,sum;
    while(scanf("%lld %lld",&n,&m))
    {
        if(n%2==0)
        {   n=n/2;
            sum=2*(1-poww(4,n,-3*m));
            sum=sum%(-3*m)/-3;
            printf("%lld\n",sum);
        }
        else if(n%2==1)
        {
            n=n/2+1;
            sum=1-poww(4,n,-3*m);
            sum=sum%(-3*m)/-3;
            printf("%lld\n",sum);
        }
    }
    return 0;
}

F - Knight Moves 

在象棋王国,尼古拉斯.火山是一匹英俊的马,他非常幸运迎娶了白马王国的公主,他们将度蜜月,你现在是他们的女仆,火山会问你去一些地方最少需要多少步,这么简单的事当然难不倒你。由于火山是一匹马,他的移动方式将会遵守国际象棋马的走法。

输入:

输入包含一个或多个输入样例。每个测试样例将会有两个坐标,表示现在的位置和将要到达的地方,每个坐标包含一个字母(a-h)表示列和一个数字(1-8) 行,这意味这这个象棋王国是一个8* 8的矩形。

Input

输入包含一个或多个输入样例。每个测试样例将会有两个坐标,表示现在的位置和将要到达的地方,每个坐标包含一个字母(a-h)表示列和一个数字(1-8) 行,这意味这这个象棋王国是一个8* 8的矩形。

Output

每一组样例将会输出一段话 "To get from xx to yy takes n knight moves.",其中xx表示起点,yy表示终点,n为xx到yy的最短步数。

Sample Input

e2 e4

a1 b2

b2 c3

a1 h8

a1 h7

h8 a1

b1 c3

f6 f6

Sample Output

To get from e2 to e4 takes 2 knight moves.

To get from a1 to b2 takes 4 knight moves.

To get from b2 to c3 takes 2 knight moves.

To get from a1 to h8 takes 6 knight moves.

To get from a1 to h7 takes 5 knight moves.

To get from h8 to a1 takes 6 knight moves.

To get from b1 to c3 takes 1 knight moves.

To get from f6 to f6 takes 0 knight moves.

题目大意及解题思路:

马从一个点移动另一个点,棋盘为8X8的形式,马的移动有八种方式,求出马从一个点移动到另一个点所用的步数。广搜遍历所有情况就行,第一次到达之后直接结束,即是最优解。

代码实现:

#include<stdio.h>
#include<string.h>
typedef struct {
    int x,y,step;
}node;
node q[66];
int x1,y1,x2,y2,t,h,map[10][10],m=8,n=8;
int next[8][2]={1,2,2,1,1,-2,2,-1,-1,2,-2,1,-2,-1,-1,-2};
void bfs(int x,int y){
    h=t=1;
    t++;
    q[h].step=0;
    q[h].x=x;
    q[h].y=y;
    int f=0;
    while(h<t){
        for(int k=0;k<8;k++){
            int x3=q[h].x+next[k][0];
            int y3=q[h].y+next[k][1];
            if(x3==x1&&y3==y1){
                f=1;
                break;
            }
            if(x3<1||x3>m||y3<1||y3>8||map[x3][y3]==1)
            continue;
            map[x3][y3]=1;
            q[t].step=q[h].step+1;
            q[t].x=x3;
            q[t].y=y3;
            t++;
        }
        if(f==1)
        break;
        h++;
    }
}
int main(){
    char c,e;
    while(scanf("%c%d%*c%c%d",&c,&y2,&e,&y1)!=EOF){
        getchar();
        x2=c-'a'+1;
        x1=e-'a'+1;
        int v;
        if(x2==x1&&y2==y1)
        {
            v=0;
        }
        else{

            memset(map,0,sizeof(map));
            map[x2][y2]=1;
            bfs(x2,y2);
            v=q[h].step+1;
        }

        printf("To get from %c%d to %c%d takes %d knight moves.\n",c,y2,e,y1,v);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值