目录
1.
.题目描述
在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。
比如:248 * 15 = 3720
把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是1位数,得
2 + 4 + 8 = 14 ==> 1 + 4 = 5;
1 + 5 = 6
5 * 6
而结果逐位求和为 3
5 * 6 的结果逐位求和与3符合,说明正确的可能性很大!!(不能排除错误)
请你写一个计算机程序,对给定的字符串逐位求和:
输入
输入为一个由数字组成的串,表示n位数(n<1000);
输出
输出为一位数,表示反复逐位求和的结果。
样例输入
35379
样例输出
9
#include<bits/stdc++.h>
using namespace std;
#define ll long long
string s;
stringstream ss;
void jy(string &s){
ll sum=0;
for(int i=0;i<s.length();i++){
sum+=s[i]-'0';
}
ss.clear();
ss<<sum;
ss>>s;
}
int main(){
cin>>s;
while(s.length()>1){
jy(s);
}
cout<<s;
return 0;
}
2.
题目描述
小h前往美国参加了蓝桥杯国际赛。小h的女朋友发现小h上午十点出发,上午十二点到达美国,于是感叹到“现在飞机飞得真快,两小时就能到美国了”。
小h对超音速飞行感到十分恐惧。仔细观察后发现飞机的起降时间都是当地时间。由于北京和美国东部有12小时时差,故飞机总共需要14小时的飞行时间。
不久后小h的女朋友去中东交换。小h并不知道中东与北京的时差。但是小h得到了女朋友来回航班的起降时间。小h想知道女朋友的航班飞行时间是多少。
对于一个可能跨时区的航班,给定来回程的起降时间。假设飞机来回飞行时间相同,求飞机的飞行时间。
输入
从标准输入读入数据。
一个输入包含多组数据。
输入第一行为一个正整数T,表示输入数据组数。
每组数据包含两行,第一行为去程的 起降 时间,第二行为回程的 起降 时间。
起降时间的格式如下
h1:m1:s1 h2:m2:s2
或
h1:m1:s1 h3:m3:s3 (+1)
或
h1:m1:s1 h4:m4:s4 (+2)
表示该航班在当地时间h1时m1分s1秒起飞,
第一种格式表示在当地时间 当日 h2时m2分s2秒降落
第二种格式表示在当地时间 次日 h3时m3分s3秒降落。
第三种格式表示在当地时间 第三天 h4时m4分s4秒降落。
对于此题目中的所有以 h:m:s 形式给出的时间, 保证 ( 0<=h<=23, 0<=m,s<=59 ).
输出
输出到标准输出。
对于每一组数据输出一行一个时间hh:mm:ss,表示飞行时间为hh小时mm分ss秒。
注意,当时间为一位数时,要补齐前导零。如三小时四分五秒应写为03:04:05。
样例输入
3 17:48:19 21:57:24 11:05:18 15:14:23 17:21:07 00:31:46 (+1) 23:02:41 16:13:20 (+1) 10:19:19 20:41:24 22:19:04 16:41:09 (+1)
样例输出
04:09:05 12:10:39 14:22:05
首先先学习游戏getline的用法
getline相比于cin的优势在于可以读取table和空格(可以忽略回车)
#include<iostream>
#include<string>
using namespace std;
int main(){
string str;
while(getline(cin,str)){
cout<<str;
}
return 0;
}
本题最大的难度在输入
下面是借鉴来的代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int get_second(int h, int m, int s){
return h * 3600 + m * 60 + s;
}
int get_time(){
string line;
getline(cin, line); //同样忽略输入的回车
if(line.back() != ')') line += " (+0)";
int h1, m1, s1, h2, m2, s2, d;
sscanf(line.c_str(), "%d:%d:%d %d:%d:%d (+%d)", &h1, &m1, &s1, &h2, &m2, &s2, &d);
return get_second(h2, m2, s2) - get_second(h1, m1, s1) + d * 24 * 3600;
}
int main(){
int t;
scanf("%d", &t);
string line;
// getline(cin, line); //忽略掉第一行的回车,因为scanf是不读入回车的
getchar();//读入回车,不知道为什么,读就对了
while(t--){
int time = (get_time() + get_time()) / 2;//去的时间 = 飞行时间 - 时差。回来的时间 =飞行时间 时间 + 时差。去加上回来就减掉,去的时候减去时差回来就加上。所以实际飞行时间= (去的时间 + 回来的时间) / 2
int hour = time / 3600, minute = time % 3600 / 60, second = time % 60;
printf("%02d:%02d:%02d\n", hour, minute, second);
}
return 0;
}
3.
题目描述
如图所示的螺旋折线经过平面上所有整点恰好一次。
对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。
例如dis(0, 1)=3, dis(-2, -1)=9
给出整点坐标(X, Y),你能计算出dis(X, Y)吗?
输入
X和Y
输出
输出dis(X, Y)
样例输入
0 1
样例输出
3
这题本来是使用暴力解法不过失败了可见蓝桥杯已经不再是暴力杯了
暴力代码如下
#include<stdio.h>
int main(){
int x=0,y=0,h,l,z,s,i,cnt=0;
int a,b;
scanf("%d %d",&a,&b);
for(h=1,l=1;;h++,l++){
if(h%2!=0)z=-1;
else z=1;
if(l%2!=0)s=1;
else s=-1;
//cout<<h <<l <<z <<s <<endl;
for(i=1;i<=h;i++){
x+=z;
// cout<<x<<endl;
cnt++;
if(x==a&&y==b)break;
}
if(x==a&&y==b)break;
for(i=1;i<=l;i++){
y+=s;
// cout<<y<<endl;
cnt++;
if(x==a&&y==b)break;
}
if(x==a&&y==b)break;
}
printf("%d",cnt);
return 0;
}
此题需要找规律
本题本来直接模拟大概能过80%的数据,其实直接找规律就行,可以看下图,我们把它补全成正方形,相邻两个正方形的差为8,成等差数列。然后每次相对左下角开始算需要求的位置与该位置的距离
正确代码如下
#include<cstdio>
#include<iostream>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
int main(void) {
int x, y;
cin >> x >> y;
ll n = max(abs(x), abs(y));//找到在第几个正方形上
ll ans = 0;
ll temp = 0;
if (x >= y) {//右下方的三角形
ans = 8 * n + n * (n - 1) * 8 / 2;//除2要放在后面哦,不然可能有误差,这边是等差数列求和
temp = x + n + y + n;//这基本就是看图找规律了
ans -= temp;
}
else {//左下方的三角形
temp = x + n + y + n;.//这基本就是看图找规律了
n--;
ans = 8 * n + n * (n - 1) * 8 / 2; //这里算的是n-1层总共的路程
ans += temp;
}
cout << ans;
return 0;
}
4.
题目描述
n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数。
(报数是从1报起)当报到 k 的时候,这个人就退出游戏圈。下一个人重新从1开始报数。
求最后剩下的人的编号。这就是著名的约瑟夫环问题。
本题目就是已知 n,k 的情况下,求最后剩下的人的编号。
输入
题目的输入是一行,2个空格分开的整数n, k
约定:0 < n,k < 1百万
输出
要求输出一个整数,表示最后剩下的人的编号。
样例输入
10 3
样例输出
4
这类题主要是找规律可以参考一下这篇文章约瑟夫环——公式法(递推公式)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int f[maxn];
int main() {
int n,k;
cin>>n>>k;
f[1]=0;
for(int i=2; i<=n; i++) {
f[i]=(f[i-1]+k)%i;
}
cout<<f[n]+1<<endl;
return 0;
}
5.
你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家
预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
输出
一个整数表示答案。
样例输入
7 ....... .##.... .##.... ....##. ..####. ...###. .......
样例输出
1
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
struct node
{
int x,y;
};
queue<node>q;
char mapp[N][N];
bool vis[N][N];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,ans;
bool flag=0;
int total,none,centre;
void bfs(int u,int v)
{
vis[u][v]=0;
q.push({u,v});
while(!q.empty())
{
node tmp=q.front();
if(mapp[tmp.x][tmp.y+1]=='#'&&mapp[tmp.x][tmp.y-1]=='#'&&mapp[tmp.x-1][tmp.y]=='#'&&mapp[tmp.x+1][tmp.y]=='#')centre++;
q.pop();
for(int i=0;i<4;i++)
{
int tmp1,tmp2;
tmp1=tmp.x+dx[i];
tmp2=tmp.y+dy[i];
if(tmp1>=1&&tmp1<=n&&tmp2>=1&&tmp2<=n&&vis[tmp1][tmp2]==1){q.push({tmp1,tmp2});vis[tmp1][tmp2]=0;}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",mapp[i]+1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(mapp[i][j]=='#')vis[i][j]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(vis[i][j]==1)
{
centre=0;
bfs(i,j);
total++;
if(!centre){none++;}
}
}
}
cout<<none;
return 0;
}