问题 A: 水下机器人
题目描述
潜水机器人潜入水深h米的湖中进行水下作业,从它在水中的位置到水面的距离为它的水下深度。机器人最初的水下深度为s米,当它不再水面(水下深度>0)时,一个u指令可使它上浮1米;当它不再湖底(水下深度<h)时,d指令可使它下沉1米。但它在水面时,u指令时无效的;在湖底时,d指令时无效的。
现给出一个指令序列(其中包含u或d字符),请你求出执行完整个指令序列后,机器人的水下深度。
输入
第一行依次为h和s。0<=s,s<=h,但0<h<100。
第二行是一个长度不超过100的指令字符串。
输出
只有一个数, 就是机器人最后的水下深度。
样例输入 Copy
9 1
uduudd
样例输出 Copy
2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n,s;
cin>>n>>s;
string a;
cin>>a;
int la = a.size();
for(int i = 0; i <= la - 1; i++)
{
if(a[i] == 'u')
{
if(s>0) s--;
}
if(a[i] == 'd')
{
if(s<n) s++;
}
}
cout<<s<<endl;
return 0;
}
问题 E: 数列游戏
题目描述
小明最近为了锻炼智力,在玩一个数列求和的游戏。设数列的长度为n,每一个数字都是整数,且在[-1000,1000]范围内,即范围是-1000~1000。
游戏规则:小明可以从这个数列里面选一串任意长度的连续子串并求和,小明想知道子串和绝对值的最大值是多少,你能帮帮他吗?
绝对值:正数的绝对值为本身,负数的绝对值为它的相反数。
如5 的绝对值为5,-7 的绝对值为7 。
输入
输入共两行,第一行为一个整数n,第二行为n 个整数。
输出
输出一个数,为数列子串和绝对值的最大值。
样例输入 Copy
【输入样例1】
10
-562 232 969 201 -111 378 -610 127 245 932
【输入样例2】
10
868 -838 -958 200 867 -920 -493 114 -800 757
【输入样例3】
10
-607 -260 -270 -833 560 -280 404 -542 560 -115
样例输出 Copy
【输出样例1】
2363
【输出样例2】
2828
【输出样例3】
1970
提示
【样例解释】
对于样例1,可以发现232+969+201-111+378-610+127+245+932=2363 所以2363 是最大的绝对值。
对于样例2,可以发现-838+-958+200+867+-920+-493+114+-800= -2828 所以2828 是最大的绝对值。
【数据规模】
对于20% 的数据,满足n<=10
对于50% 的数据,满足n<=100
对于70% 的数据,满足n<=1000
对于100% 的数据,满足n<=1000000
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1000005;
int n;
long long pre_sum[MAXN];
long long pre_min[MAXN];
long long pre_max[MAXN];
long long ans;
long long a[MAXN];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
pre_sum[i]=pre_sum[i-1]+a[i];
}
//这题先看一半 比如只看取正数区间和最大值
//我们要的是一个x~y的区间使区间和最大
//x~y = 1~n 减去 1~(x-1)[最小值] 再减去 (y+1)~n
//首先我们通过pre_min[i]得到从1~i的最小区间和从而解决减去1~(x-1)[最小值]的问题
//然后随着 i 从 1 ++到 n 我们最终可以确定y的值
//知道最大区间和 知道区间和 求abs最大易如反掌好吗
for(int i=1;i<=n;i++)
{
//求最大区间和的步骤
pre_min[i]=min(pre_min[i-1],pre_sum[i-1]);
ans=max(ans,abs(pre_sum[i]-pre_min[i]));
//求最小区间和的步骤
//1~i范围内最大的前缀和
//起点一定是1 但终点不一定是i
pre_max[i]=max(pre_max[i-1],pre_sum[i-1]);
//pre_sum[i]-pre_max[i]
//1~i前缀和 减去 1~i范围内最大的前缀和
ans=max(ans,abs(pre_sum[i]-pre_max[i]));
}
cout<<ans<<'\n';
}
补题E的时候学到了如何二分求子区间最大和
很值
虽然最后还是没用上
int solve ( int l, int r )
{
if ( l == r ) return a [ l ];
int mid = l + ( r - l >> 1 ), sum = 0, ansl = -1e9, ansr = -1e9;
for ( int i = mid; i >= l; i -- )
ansl = max ( ansl, ( sum += a [ i ] ) );
sum = 0;
for ( int i = mid + 1; i <= r; i ++ )
ansr = max ( ansr, ( sum += a [ i ] ) );
return max ( max ( solve ( l, mid ), solve ( mid + 1, r ) ), ansl + ansr );
}
问题 I: 收集瓶盖赢大奖
题目描述
商店推出新活动收集10个‘幸运’瓶盖或者收集20个‘鼓励’瓶盖就可以换一份神秘大奖。
输入
第一行,一个整数n(n<=1000)。
以下n行每行两个数第一个是‘幸运’瓶盖数,第二个是‘鼓励’瓶盖数。
输出
以下n行如果能兑换便输出“True”,否则便输出“False”
样例输入 Copy
2
11 19
3 19
样例输出 Copy
True
False
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
long long a,b;
while(n--)
{
cin>>a>>b;
if(a >= 10 || b >= 20)
cout<<"True"<<endl;
else
cout<<"False"<<endl;
}
return 0;
}
问题 J: 石头剪刀布
题目描述
AB两人石头剪刀布,0是石头,1是剪刀,2是布。赢一局加两分,平局各加一分。
输入
一个正整数n(n<=100)
以下n行分别是AB两人出的是什么
输出
两个正整数分别是AB两人的分数
样例输入 Copy
3
0 1
2 2
0 2
样例输出 Copy
3 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
int ansa = 0;
int ansb = 0;
while(n--)
{
int a,b;
cin>>a>>b;
if(a == b)
{
ansa++;
ansb++;
}
else if(a + b == 1)
{
if(!a) ansa += 2;
else ansb += 2;
}
else if(a + b == 2)
{
if(a == 2) ansa += 2;
else ansb += 2;
}
else if(a + b == 3)
{
if(a == 1) ansa += 2;
else ansb += 2;
}
}
cout<<ansa<<' '<<ansb<<endl;
return 0;
}
问题 K: 幸运数字
题目描述
一个数能被7整除或10进制中含有7被称为幸运数字。
输入
一个整数n(n≤1000)
输出
求1—n幸运数字的和。
样例输入 Copy
21
样例输出 Copy
59
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
bool check(int x)
{
if(x % 7 == 0)
return true;
while(x)
{
int t = x % 10;
if(t == 7) return true;
x = x / 10;
}
return false;
}
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
long long ans = 0;
for(int i = 1; i <= n; i++)
{
if(check(i)) ans+=i;
}
cout<<ans<<endl;
return 0;
}
问题 L: 数苹果
题目描述
苹果丰收了,有n堆苹果,小红就在苹果堆旁。小红已经知道了每堆苹果有多少个。她要问一问从第a堆到第b堆一共有多少个苹果。
输入
输入数字n,然后输入n个数据。再输入m,然后输入m行数据。
输出
输出m次a到b堆一共有多少个。
样例输入 Copy
5
1 2 3 4 5
3
1 3
2 4
1 5
样例输出 Copy
6
9
15
提示
对于%80的数据:0≤n≤10000;
对于%100的数据:0≤n≤100000。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
long long a[100005] = {0};
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
long long t;
for(int i = 1; i <= n; i++)
{
cin>>t;
a[i] = a[i - 1] + t;
}
long long m;
cin>>m;
int s,e;
while(m--)
{
cin>>s>>e;
if(s > e) swap(s, e);
//这个悲伤的故事揭露了endl的黑暗与邪恶
cout<<(a[e] - a[s - 1])<<'\n';
}
return 0;
}