题面PDF
(当然这个直接进比赛也能看得到)←比赛链接
A. Archmage
题意:每次sum+y,sum大于x可以-x,sum+y大于n时等于n,问在m次后一共可以减几次x。
虽然是比较水的一道题,但是仍然做了快一个小时…甚至写暴力算法之后用随机数找错误这种事情都干上了,结果最后发现ac代码跟wa了好几遍的代码就差了一个判断,直接裂开了。
这道题由于他有一个x+y<=n,直接简单了不少(虽然搞了快一个小时才发现这个),因为x+y<=n,所以不会出现题目给的sum+y>n的情况,也就是说在x>y的时候,加了m次y,而y不会损失,那么总共可以用的mana数量就是n+(m-1)*y(这里不用m而用m-1是因为顺序是先减x后加y,最后一次加y后不会减x了),这时问题就转化为了总量为n+(m-1)*y,在m次内,最多可以减去多少次x。那么这个时候只需要算n+(m-1)*y中包含多少个x就好了,也就是(n+(m-1)*y)/x。当然还需要做一次判断,判断这个值是否大于m,大于m则输出m就好了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
int main(){
//ios::sync_with_stdio(false);
long long n,x,y,z,m,t,ans = 0;
cin>>t;
while(t--){
scanf("%lld %lld %lld %lld",&n,&m,&x,&y);
if(x>y&&((m-1)*y+n)/x<=m){
printf("%lld\n",((m-1)*y+n)/x);
}
else{
printf("%lld\n",m);
}
}
return 0;
}
B. Bamboo Leaf Rhapsody
签到题,算最小距离
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
int main(){
//ios::sync_with_stdio(false);
int n,x,y,z;
double ans = 99999999;
cin>>n;
for(int i= 0;i<n;i++){
cin>>x>>y>>z;
ans = min(ans,sqrt(x*x+y*y+z*z));
}
printf("%.3f",ans);
return 0;
}
C. Cheat Sheet
题意:求在限定字符数量下最多可以有几个不同的字符串。
贪心,首先将重复的去除,然后按照剩余字符串长度从大到小删除,直到剩余字符串长度和小于题目要求,注意空格数量。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
priority_queue<ll> a;
int main() {
ios::sync_with_stdio(false);
ll n, x, y, z, m, t, ans = 0,total = 0;
cin>>n>>m;
map<string, bool> q;
string s;
for(int i = 0;i<m;i++) {
cin >> s;
if (!q[s]) {
ans++;
q[s] = true;
total += s.size();
a.push(s.size());
}
}
total+=ans-1;
while(total>n){
total-=a.top();
total--;
a.pop();
ans--;
}
cout<<ans<<'\n';
return 0;
}
D. Disaster Recovery
题意:一个无向图,给出任意边,边权为两顶点对应斐波那契数列上的数之和,求该图最小生成树,并找到最小生成树下最大顶点出度。
其实就是结构体排序+最小生成树的kruskal算法,因为题目数据范围是105,所以不能直接把斐波那契数列算出并求边权。在比较两边权时,可以通过比较两条边终点大小(由于是无向图,这里定义两顶点中较大者为终点,另一点为起点),较大的那一条边边权一定较大,终点相同的时候起点较大的边边权较大,这样就可以讲边排序,进一步应用kruskal最小生成树算法,求出最大顶点出度。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
struct node{
int u,v;
};
vector<node> a;
long long f[100005];
long long p[100005];
bool cmp(node x,node y){
if(x.v!=y.v){
return x.v<y.v;
}else{
return x.u<y.u;
}
}
void init(long long n){
for(int i = 1;i<=n;i++){
f[i] = i;
}
}
int getf(int v){
if(f[v]==v){
return v;
}else{
f[v] = getf(f[v]);
return f[v];
}
}
int merge(int v,int u){
int t1 = getf(v),t2 = getf(u);
if(t1!=t2){
f[t2] = t1;
return 1;
}
return 0;
}
int main(){
ios::sync_with_stdio(false);
long long n,x,y,z,m,t,k,ans = 0,count = 0;
cin>>n>>m;
init(n);
for(int i = 0;i<m;i++){
cin>>x>>y;
node t;
if(y<x){
t.u = y;
t.v = x;
}else{
t.u = x;
t.v = y;
}
a.push_back(t);
}
sort(a.begin(),a.end(),cmp);
for(int i = 0;i<m;i++){
if(merge(a[i].u,a[i].v)){
count++;
p[a[i].u]++;
p[a[i].v]++;
ans = max(ans,p[a[i].u]);
ans = max(ans,p[a[i].v]);
}
if(count == n-1){
break;
}
}
cout<<ans;
return 0;
}
H. Hay Mower
题意:给出一个n*m矩阵,代表该点每一时间草的生长量,给出k条割草指令,问一共割了多少草。
首先,
其次这道题其实就是对较大数处理稍微有点难度,其他的基本是程设一难度,直接看代码吧。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
long long a[505][505];
long long book[505][505];
int main(){
ios::sync_with_stdio(false);
long long n,x,y,z,m,t,k,ans = 0;
cin>>n>>m>>k;
memset(book,0,sizeof(book));
char s;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin>>a[i][j];
a[i][j]%=998244353;
}
}
while(k--){
cin>>s>>x>>t;
//t%=998244353;
if(s=='r'){
for(int i = 1;i<=m;i++){
ans+=(t-book[x][i])%998244353*a[x][i]%998244353;
book[x][i] = t;
}
}else if(s=='c'){
for(int i = 1;i<=n;i++){
ans+=(t-book[i][x])%998244353*a[i][x]%998244353;
book[i][x] = t;
}
}
ans%=998244353;
}
cout<<ans;
return 0;
}
这里有一些取余应该没有那么必要,但总之这样是a掉了(逃