注:本次所有习题大部分是由ChatGPT解答并微调,会附上相关问答:
1.打靶
请用C++写代码:小码哥在练习射箭,他要射穿n个靶子,且每个靶子有高度hi。箭会因为受到靶子的摩擦力而下坠,当射穿一个靶子后箭的高度会下降1。小码哥可以射任意高度的箭。求出小码哥最少需射几箭。( 1 ≤n, hi≤10^6 ) 。第一行一个整数n。第二行n个整数hi 。输出一个整数,表示小码哥最少需要射几箭。
#include<iostream>
using namespace std;
int h[1000001];
int main(){
int n,k;
int shoot = 0;
cin >> n;
for(int i=0;i<n;i++){
cin >> k;
if(!h[k]) shoot++;
else h[k]--;
h[k-1]++;
}
cout << shoot;
}
2.挑兵挑将
ChatGPT未能解决
#include<bits/stdc++.h>
#define maxn 25
using namespace std;
int n,k,m;
int a[maxn];
int solve(int p,int d,int t){
while(t--){
do{
p=(p+d+n-1)%n+1;
}
while(a[p]==0);
}
return p;
}
int main()
{
while(scanf("%d%d%d",&n,&k,&m)==3&&n){
for(int i=1;i<=n;i++){
a[i]=n;
}
int left=n;
int p1=n;
int p2=1;
while(left){
p1=solve(p1,1,k);
p2=solve(p2,-1,m);
printf("%3d",p1);
left--;
if(p2!=p1){
printf("%3d",p2);
left--;
}
a[p1]=a[p2]=0;
if(left)printf(",");
}
printf("\n");
}
return 0;
}
3.照亮街道
请用C++写代码:有一条可以视为线段的街道,长度为L,其中有n个路灯,每个路灯能照亮的半径都是相同的,求最小的照亮半径r使得整条街道上的每一个点都能被照亮。一行一个数表示答案两个正整数n,L。第二行为初始n个实数,表示n个路灯的坐标数据保证在0到L之间。
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
int main(){
int n,L;
cin>>n>>L;
double *pos=new double[n];
for(int i=0;i<n;i++)
cin>>pos[i];
sort(pos,pos+n);
double ans=max(pos[0],L-pos[n-1]);
for(int i=1;i<n;i++){
ans=max(ans,(pos[i]-pos[i-1])/2);
}
//cout<<n<<" "<<L<<endl;
//cout<<ans<<endl;
printf("%.2lf",ans);
return 0;
}
4.字符矩阵(过9个)
C++写代码:给你一个n * m 的小写字符矩阵,你可以选择删除一些列,使得剩下的字符矩阵的每一行的字符串从上到下的字典序非减。即字符串s和 t具有相等的长度,s在字典上大于t并且 s中 s和t的最大公共前缀(前缀可能为空)之后的字符按字母顺序大于t的相应字符。 求最少删除多少列?第一行输入两个整数n, m接下来n行每行输入m个字符。输出一个整数表示最少删除的列。
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
string s[105];
for(int i=0;i<n;i++) cin>>s[i];
int ans=0;
for (int j=m-1;j>=0;j--) {
bool ok=true;
for (int i=0;i<n-1;i++)
if (s[i][j]>s[i+1][j]) ok=false;
if (!ok) ans++;
}
cout<<ans<<endl;
return 0;
}
5.移水造海
ChatGPT未能解决
#include <bits/stdc++.h>
using namespace std;
int a[10005];
int main(){
int n, maxn = 0, ans = 0;
cin >> n;
for (int i =0; i<n; i++){
cin >> a[i];
maxn =max(maxn,a[i]);
}
for (int i= 1; i<= maxn; i++){
int last = -1;
for (int j =0;j<n; j++){
if (a[j] >= i){
//cout<<last<<" "<<j<<" "<<j - last - 1<<endl;
if (last != -1)
ans += j - last - 1;
last = j;
}
}
}
cout << ans;
return 0;
}
6.找1
用C++写代码:最近小码哥爱上二进制,他特别喜欢全是1的二进制串,但通常会有0。于是他给你一个二进制字符串,问你字符都为1的子串的个数(结果对10^9+7取模)输入—个二进制字符串。输出 所有字符都为1的子串个数
#include<iostream>
#include<string>
using namespace std;
const int mod = 1000000007;
int main()
{
string str;
cin >> str;
int ans = 0, num = 0;
for (unsigned int i = 0; i < str.length(); i++) {
if (str[i] == '1') {
num++;
} else {
ans = (ans + num * (num + 1) / 2) % mod;
num = 0;
}
}
ans = (ans + num * (num + 1) / 2) % mod;
cout << ans << endl;
return 0;
}
7.连续的串
用C++写代码:给你一个字符串,找出现次数最多的长度为2的子串。第一行为一个正整数n ,表示给出字符串的长度,第二行为字符串。输出所求的串,若有多个结果,输出字典序最小的
#include <iostream>
#include <algorithm>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
int n;
cin >> n;
string s;
cin >> s;
unordered_map<string,int> mp;
for (int i = 0; i < n-1; ++i)
{
string tmp = s.substr(i,2);
mp[tmp]++;
}
int max_time = 0;
string res;
for (auto e : mp)
{
if (e.second > max_time)
{
max_time = e.second;
res = e.first;
}else if (e.second == max_time && e.first < res)
{
res = e.first;
}
}
cout << res << endl;
return 0;
}
8.伯兰语(过10个)
用C++写代码:伯兰语有五个元音字母,分别是a,e,i,o,u。伯兰语单词中的每一个非元音(除了n)后都是元音(没有字母也不行,即单词末尾必须是a,e,i,o,u,n这六个字符之一)。而元音和n没有此限制。如 harakiri,yupie,man和nbo都是符合规范的,而horse , king,my ,nz都不符合。给你一个单词,问是否符合伯兰语单词的规范。输入仅一行,是你需要判断是否符合规范的单词。输出仅一行,若符合则输出YES,否则输出 NO
#include<iostream>
#include<string>
using namespace std;
int main()
{
string w;
cin >> w;
int len = w.length();
char end = w[len-1];
bool flag = true;
for(int i=0;i<len-1;i++)
{
if(w[i]!='a' && w[i]!='e' && w[i]!='i' && w[i]!='o' && w[i]!='u' && w[i]!='n')
{
if(end!='a' && end!='e' && end!='i' && end!='o' && end!='u' && end!='n')
{
flag = false;
break;
}
}
}
if(flag==true)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
9.数据流的中位数
用C++写代码:中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。 请帮小码哥设计一个堆结构,支持以下两种操作的系统: +num 代表从数据流中添加一个整数k到系统中( 0<k <2^(32) )。?代表返回目前所有元素的中位数。第—行输入—个整型n(n ≤100000)第二行输入n个操作。出现?就输出中位数,每个操作一行,保证每次查询都合法。
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
priority_queue<int, vector<int>, greater<int>> qmin;
priority_queue<int, vector<int>, less<int>> qmax;
int n;
int main() {
cin >> n;
while (n--) {
string op;
cin >> op;
if (op[0] == '+') {
int num;
cin >> num;
if (qmax.empty() || qmax.top() > num) {
qmax.push(num);
} else {
qmin.push(num);
}
if (qmax.size()<qmin.size()) {
qmax.push(qmin.top());
qmin.pop();
} else if (qmax.size() > qmin.size() + 1) {
qmin.push(qmax.top());
qmax.pop();
}
} else if (op[0] == '?') {
if((qmax.size()+qmin.size())%2)
cout << qmax.top() << endl;
else cout<<1.0*(qmax.top()+qmin.top())/2<<endl;
}
}
return 0;
}
10.竹鼠的白色季节
用C++写代码:小码哥的竹鼠养殖场中的竹鼠都在一条直线的隔间里,一共有n只竹鼠,它们的坐标分别为P1 , P2 , P3 , P4,. . .,pn(0 ≤pi ≤10^8 ),1<n ≤100000 。又到了冬季,竹鼠们也要谈恋爱,因为竹鼠们都太胖了,它们的活动范围有限,这里统一规定它们的活动范围为d (0≤d≤10^4 )。由于竹鼠之间也需要双向奔赴,所以如果两只竹鼠之间的距离小于等于d,则称它们是有缘的一对竹鼠,问小码哥的养殖场里一共有多少对有缘的竹鼠?注:一只竹鼠可能存在于多个有缘的竹鼠对之中,多只竹鼠可能在同一个坐标上。第一行,两个用空格隔开的数字n和d。第二行,n个整数,分别表示n只竹鼠在直线上的坐标。输出一个整数,则有缘竹鼠对。优化循环 算法。
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
long long n,d;
cin >> n >> d;
long long *arr=new long long[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
sort(arr,arr+n);
int l=0,r=0;
long long ans=0;
while(l<n){
if(arr[r]-arr[l]<=d){
r++;
}else{
ans += r-l-1;
l++;
}
if(r==n){
ans+=r-l-1;
break;
}
}
cout<<ans<<endl;
return 0;
}
11.换换换
ChatGPT未能解决
#include <bits/stdc++.h>
#define N 50005
using namespace std;
int n, m,t;
string s[N];
map<string,int> mp;
int main(){
string tmp;
cin >>n>>m >>t;
for (int i = 1; i<= n; i++){
cin >> tmp;
s[i] = tmp;
mp[tmp] = i;
}
while (t--){
int p1,p2;
cin >>p1 >> p2;
swap(s[p1],s[p2]);
swap(mp[s[p1]], mp[s[p2]]);
}
while (m--){
cin >> tmp;
cout << mp[tmp] << endl;
}
return 0;
}
12.银行账户
用C++写代码:据说对银行账户进行盗窃时,如果只盗取小数点下的数值,就不容易引起注意,所以你决定进行尝试。银行总共有n个账户,m次转账,对每次转账,你可以盗取(转账金额-转账金额向下取整)的资金,并使转入账户的警戒值增加相同数值,当任意账户的警戒值>1,或者无法实现转账(转出账户余额不足),或者m次转账全部完成,你停止盗取,请计算总盗取金额。第一行n,m,表示有n个账户,m条转账记录;第二行n个实数,表示每个账户的资金;接下来m行,每行有三个参数;整数x,整数y,实数z,分别表示转出账户,转入账户,和转账金额。输出盗取金额,保留两位小数。
#include<bits/stdc++.h>
using namespace std;
int n,m,x,y;
double a[1005],z,f[ 1005],ans;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=0;i<m;i++){
cin>>x>>y>>z;
if(a[x]<z)
break;
else {
a[x]-=z;
f[y]=f[y]+z-floor(z);
ans=ans+z-floor(z);
a[y]+=floor(z );
if(f[y]>1)
break;
}
}
printf("%.2lf",ans);
return 0;
}
13.花园浇水
ChatGPT未能解决
#include <iostream>
using namespace std;
int ans=1;
int main()
{
int n,area[1000],height[1000];
cin >> n;
for (int i=1;i<=n;i++)
{
cin >> height[i];
}
height[0]=1e9;
height[n+1]=1e9;
for(int i=1;i<=n;i++)
{
int l=i,r=i;
if(height[i]>=height[i-1])
{
l=i;
while(height[l]>=height[l-1]) l--;
}
if(height[i]>=height[i+1])
{
r=i;
while(height[r]>=height[r+1]) r++;
}
//cout<<height[i]<<" "<<r<<" "<<l<<endl;
ans=max(ans,r-l+1);
}
cout<<ans;
return 0;
}
14.奇怪的和
ChatGPT未能解决
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a,idx=1;
vector <pair<int, int>> re[100005];
map<int,int> mp;
long long ans;
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a;
if(!mp[a]){
mp[a]=idx++;
re[mp[a]].push_back({i,j});
}
else{
for(int k=0;k<re[mp[a]].size();k++)
ans+=abs(i-re[mp[a]][k].first)+abs(j-re[mp[a]][k].second);
re[mp[a]].push_back({i,j});
}
}
}
cout<<ans;
return 0;
}
15.线段覆盖
ChatGPT未能解决
#include <iostream>
using namespace std;
long long n, m, d, l;
int main() {
cin >> n >> d >> m >> l;
long long a = 0, b = 0;
for (long long i = 1; i <= n; i++) {
a = (i - 1) * m + l, b = i * m - 1;
if (a / d != b / d) break;
}
cout << (a / d + 1) * d << endl;
return 0;
}