往年真题知多少1

题目名称:观星star

时间限制:1000ms内存限制:64MB提交通过率:33%

题目描述


Jimmy 和 Symbol 约好一起看星星,浩瀚的星空可视为一个长为 N、宽为 M 的矩阵,矩阵中共有 N×M 个位置,一个位置可以用坐标 (i,j)(1≤i≤N,1≤j≤M)来表示。每个位置上可能是空的,也可能有一个星星。
对于一个位置 (i,j),与其相邻的位置有左边、左上、上面、右上、右边、右下、下面、左下 8 个位置。相邻位置上的星星被视为同一个星座,这种关系有传递性,例如若 (1,1),(1,2),(1,3)三个位置上都有星星,那么这三个星星视为同一个星座。包含的星星数量相同的星座被视为一个星系(一个星系中的星座不一定相邻),星系的大小为星系中包含的所有星星数量。
由于 Symbol 太喜欢星系了,他就想考一考 Jimmy,让 Jimmy 求出星空中有多少个星系,他还想知道,最大的星系有多大。

输入描述

第一行两个整数 N,M 表示矩阵的长宽。
接下来 N 行每行 M 个字符,每个字符只可能是.或*。这 N 行中第 i 行的第 j 个字符是*表示位置 (i,j) 上有一个星星,否则表示它是空的。

数据规模:
对于 20% 的数据,N,M≤20,最大星系大小不超过 200。
对于 50% 的数据,N,M≤400。
对于 70% 的数据,N,M≤1100。
对于 100% 的数据,2≤N,M≤1500,最大星系大小不超过 100000。

输出描述

仅一行两个整数,用空格分隔开,分别表示星系的数量与最大星系的大小。

样例1

输入

5 7

*......

..**..*

.*...*.

...*...

....*..

输出

3 4

样例2

输入

10 10

**..**.**.

***....*..

*...**.**.

...*..*...

..........

**...**.*.

..*.*....*

..........

***..*.*..

.***..*...

输出

4 12

AC代码

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
typedef pair<int,int> PII;
const int N=1505,M=100005;
int n,m;
char g[N][N];
PII q[N*N];//手写队列
int b[M];
int ans,res;

int bfs(int sx,int sy){
	int cnt=1,hh=0,tt=0;
	q[0]={sx,sy};
	g[sx][sy]='.';
	while(hh<=tt){
		PII t=q[hh++];
		for(int i=t.x-1; i<=t.x+1; i++){
			for(int j=t.y-1; j<=t.y+1; j++){
				if(i==t.x && j==t.y) continue;
				if(i<0 || i>=n || j<0 || j>=m) continue;
				if(g[i][j]=='.') continue;
				
				q[++tt]={i,j};
				g[i][j]='.';
				cnt++;
			}
		}
	}
	
	return cnt;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0; i<n; i++)
		scanf("%s",&g[i]);
	
	for(int i=0; i<n; i++){
		for(int j=0; j<m; j++){
			if(g[i][j]=='*'){
			    int k=bfs(i,j);
				if(!b[k])
					res++;
				
				b[k]++;
				ans=max(ans,b[k]*k);
			}
		}
	}
	printf("%d %d\n",res,ans);
	return 0;
}

题目名称:优秀的拆分

时间限制:1000ms内存限制:64MB提交通过率:49%

题目描述


一般来说,一个正整数可以拆分成若干个正整数的和。
例如,1=1,10=1+2+3+4 等。对于正整数 n 的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆分下,n 被分解为了若干个不同的 2 的正整数次幂。注意,一个数 x 能被表示成 2 的正整数次幂,当且仅当 x 能通过正整数个 2 相乘在一起得到。
例如,10=8+2=2^3+2^1是一个优秀的拆分。但是,7=4+2+1=2^2+2^1+2^0就不是一个优秀的拆分,因为 1 不是 2 的正整数次幂。
现在,给定正整数 n,你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案。

输入描述

输入只有一行,一个整数n,代表需要判断的数。

数据规模与约定:
对于 20% 的数据,n≤10。
对于另外 20% 的数据,保证 n 为奇数。
对于另外 20% 的数据,保证 n 为 2 的正整数次幂。
对于 80% 的数据,n≤1024。
对于 100% 的数据,1≤n≤1×10^7。

输出描述

如果这个数的所有拆分中,存在优秀的拆分。那么,你需要从大到小输出这个拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的。
若不存在优秀的拆分,输出 -1。

样例1

输入复制

6

输出

4 2

样例2

输入

7

输出

-1

AC代码

#include <bits/stdc++.h>
using namespace std;

int n, num[100], i, base = 1;

int main(){
    cin >> n;
    if (n % 2 == 1){
        cout << -1;
    } else {
        while (n != 0){
            //拆分数位并还原成10进制数
            num[i] = n % 2;
            n = n / 2;
            num[i] = num[i] * base;
            base = base * 2;
            i++;
        } 
    } 
    for (int j = i - 1; j >= 1; j--){
        if (num[j] != 0){
            cout << num[j] << " ";
        }
    }
    return 0;
}

题目名称:潜伏者

时间限制:1000ms内存限制:64MB提交通过率:32%

题目描述


R 国和S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动。历尽艰险后,潜伏于S 国的R 国间谍小C 终于摸清了S 国军用密码的编码规则:
1.S 国军方内部欲发送的原信息经过加密后在网络上发送,原信息的内容与加密后所得的内容均由大写字母‘A’-‘Z’构成(无空格等其他字符)。
2.S 国对于每个字母规定了对应的“密字”。加密的过程就是将原信息中的所有字母替换为其对应的“密字”。
3.每个字母只对应一个唯一的“密字”,不同的字母对应不同的“密字”。“密字”可以和原字母相同。
例如,若规定‘A’的密字为‘A’,‘B’的密字为‘C’(其他字母及密字略),则原信息“ABA”被加密为“ACA”。
现在,小C 通过内线掌握了S 国网络上发送的一条加密信息及其对应的原信息。小C希望能通过这条信息,破译S 国的军用密码。小C 的破译过程是这样的:扫描原信息,对于原信息中的字母x(代表任一大写字母),找到其在加密信息中的对应大写字母y,并认为在密码里y 是x 的密字。如此进行下去直到停止于如下的某个状态:
1.所有信息扫描完毕,‘A’-‘Z’ 所有26 个字母在原信息中均出现过并获得了相应 的“密字”。
2.所有信息扫描完毕,但发现存在某个(或某些)字母在原信息中没有出现。
3.扫描中发现掌握的信息里有明显的自相矛盾或错误(违反S 国密码的编码规则)。例如某条信息“XYZ”被翻译为“ABA”就违反了“不同字母对应不同密字”的规则。
在小C 忙得头昏脑涨之际,R 国司令部又发来电报,要求他翻译另外一条从S 国刚刚截取到的加密信息。现在请你帮助小C:通过内线掌握的信息,尝试破译密码。然后利用破译的密码,翻译电报中的加密信息。

输入描述

共3行,每行为一个长度在1到100之间的字符串。
第1行为小C掌握的一条加密信息。
第2行为第1行的加密信息所对应的原信息。
第3行为R国司令部要求小C翻译的加密信息。
输入数据保证所有字符串仅由大写字母‘A’-‘Z’构成,且第1行长度与第2行相等。

输出描述

共1行。
若破译密码停止时出现2,3两种情况,请你输出“Failed”(不含引号,注意首字母大写,其它小写)。
否则请输出利用密码翻译电报中加密信息后得到的原信息。

样例1

输入

AA AB EOWIE

输出

Failed

样例2

输入

QWERTYUIOPLKJHGFDSAZXCVBN ABCDEFGHIJKLMNOPQRSTUVWXY DSLIEWO

输出

Failed

样例3

输入

MSRTZCJKPFLQYVAWBINXUEDGHOOILSMIJFRCOPPQCEUNYDUMPP YIZSDWAHLNOVFUCERKJXQMGTBPPKOIYKANZWPLLVWMQJFGQYLL FLSO

输出

NOIP

AC代码

#include <bits/stdc++.h>
using namespace std;
int main(){
    char s1[101],s2[101],s3[26],s4[101];//设置s1,s2,s4依照题目正常输入 
    memset(s3,0,sizeof(s3));//将s3的值都标为0 
    cin >> s1 >> s2 >> s4;
    int lens1 = strlen(s1);
    if(lens1 < 26){//依照条件需要有二十六个密字对应的,所以先排查是否有26个字符 
        printf("Failed");//没有则输出 "Failed"
        return 0;//如果输出"Failed"则直接结束代码 
    }
    for(int i = 0;i < lens1;i++){//分解每一个密字 
        if(s3[s1[i]-'A'] == 0) s3[s1[i]-'A'] = s2[i];//如果是首次出现则直接s3记录对应字母 
        else{
            if(s3[s1[i] - 'A'] != s2[i]){ //如果该密字已经出现则进行判断其对应的字母是否与先前的相同 
                printf("Failed");
                return 0;
            }
        }
    }
    for(int i = 0;i < 26;i++){ //同时按题目要求进行判断是否出现相互矛盾的密字 
        for(int j = 0;j < 26;j++){ 
            if(s3[i] == s3[j] && i != j){
                printf("Failed");//有则输出"Failed"并结束代码 
                return 0;
            }
        }
    }
    int lens4 = strlen(s4);
    for(int i = 0;i < lens4;i++){//如果正常则进行对密字的翻译 
        printf("%c",s3[s4[i] - 'A']);//输出每一个密字对应的字母 
    }
    return 0; 
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值