【LGR-182-Div.4】洛谷入门赛 #22
A 疯狂大减价
分析:两张票的先后顺序枚举一下,求出最小值。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n, k, ans;
int main(){
cin>>n;
int a = n, b = n;
if(a >= 100) a -= 20;
if(a >= 200) a -= 50;
if(b >= 200) b -= 50;
if(b >= 100) b -= 20;
cout<<min(a,b);
return 0;
}
具体分析发现,如果可以用第二张券,那么必然可以用第一张券;如果先用第一张,不一定可以用第二张,所以先用第二张。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n, k, ans;
int main(){
cin>>n;
int b = n;
if(b >= 200) b -= 50;
if(b >= 100) b -= 20;
cout<<b;
return 0;
}
B ZngivaeL 的中考
分析:模拟,但是代码可能较为麻烦,运用前缀和思想
s[0] -- 表示 A 的数量
s[1] -- 表示 A~B 的数量
s[2] -- 表示 A~C 的数量
s[3] -- 表示 A~D 的数量
之后怎么做,相信不用多说了吧!
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int main(){
string s;
while(cin>>s){
int st[27]={0};
for(int i=0; i<s.size(); i++) st[s[i]-'A'] ++;
for(int i=1; i<4; i++) st[i] += st[i-1];
if(st[1] >= 4 && st[0]>=1) cout<<"I'm so happy.";
else if(st[2] >= 4) cout<<"This is ok.";
else cout<<"Never give up.";
cout<<endl;
}
return 0;
}
C 游乐场
分析:开数组模拟即可,其实还可以分析ans是否需要开 long long.
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N];
int main(){
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
int money = 0, ans=0;
for(int i=1; i<=n; i++){
int t = a[i] - a[i-1]; // 这段时间新增的零花钱
if(money + t > 50) money = 50;
else money += t;
ans += money / 8, money %= 8;
}
cout<<ans;
return 0;
}
D 吃苹果
分析:
求最大最小的和就是答案
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N];
int main(){
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
int mx=a[1], mn=a[1];
for(int i=1; i<=n; i++){
mx = max(mx, a[i]);
mn = min(mn, a[i]);
}
long long ans = 1ll * mx + mn;
cout<<ans;
return 0;
}
排序后,首尾求和就是答案,注意数据范围,开 long long。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N];
int main(){
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
sort(a+1, a+1+n);
long long ans = 1ll * a[1] + a[n];
cout<<ans;
return 0;
}
E 天上的气球
分析:使用二维数组记录即可;
这里可使用两个二维数组,一个记录 h,一个记录 c;
也可以使用一个二维数组,但是每个元素是一个pair<int,int> 使用 first记录 h, second记录 c;
后面如果有更低的高度就更新。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,k;
pair<int,int> a[N][N];
int main(){
cin>>n>>m>>k; int x,y,h,c;
while(k--){
cin>>x>>y>>h>>c;
if(!a[x][y].second ||a[x][y].first > h)
a[x][y] = make_pair(h, c);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cout<<a[i][j].second<<" \n"[j==m];
return 0;
}
F 神秘排列
分析:其实就是两个问题的组合
问题1:元素 1~n是否都出现了,可以使用标记数组对出现元素进行标记;
问题2:\(\forall {i}, p[i]=a[i]\),提醒:对于题目中的符号,代码中最好不变,这样思路更加清晰
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N], p[N], st[N];
int main(){
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++) {
st[a[i]] = 1;
p[a[i]] = i;
}
int s = 0;
for(int i=1; i<=n; i++) {
if(p[i] != a[i]) break;
s += st[i];
}
cout<<(s == n ? "YES" :"NO");
return 0;
}
G 道法考试
分析:其实就是看某写元素是否出现,可以使用for查询,但是效率低,可以利用set/map优化
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10, M=2e3+10;
int n,m,x, l[M];
set<int> se[N];
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++){
cin>>x; se[i].insert(x);
}
int ans = 0;
for(int i=1; i<=n; i++){
cin>>l[i];
int t = 0;
for(int j=1; j<=l[i]; j++) {
cin>>x;
t += se[i].count(x);
}
if(t == m) ans += 2;
}
cout<<ans;
return 0;
}
H 非众数
分析:将全部非空子串求出来,一个一个判断。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10, M=2e3+10;
int ans;
queue<string> q;
int main(){
string s; cin>>s;
for(int i=0; i<s.size(); i++)
for(int j=i; j<s.size(); j++)
q.push(s.substr(i, j-i+1));
while(q.size()){
s = q.front(); q.pop();
int st[27] = {0}, mx = 0;
for(int i=0; i<s.size(); i++){
st[ s[i] -'a' ] ++;
mx = max(mx, st[ s[i] - 'a']);
}
if(mx <= s.size() / 2) ans ++;
}
cout<<ans;
return 0;
}