Codeforces Round 1037 (Div. 3)
文章目录
- A. Only One Digit
- B. No Casino in the Mountains
- C. I Will Definitely Make It
- D. This Is the Last Time
- E. G-C-D, Unlucky!
- F. 1-1-1, Free Tree!
- G1. Big Wins! (easy version)
A. Only One Digit
数拆解一下,找最小的。
看样例也能明白。
#include<bits/stdc++.h>
#define LL long long
using namespace std;typedef pair<int,int> PII;void solve(){int x;cin>>x;int mn=10;while(x){mn=min(mn,x%10);x/=10;}cout<<mn<<'\n';
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int T=1;cin>>T;while(T--){solve();}return 0;
}
B. No Casino in the Mountains
贪心地,遇到0就开始记录,到k个或者越界或者遇到1就退出循环,模拟过去就行。
#include<bits/stdc++.h>
#define LL long long
using namespace std;typedef pair<int,int> PII;void solve(){int n,k;cin>>n>>k;vector<int> a(n+1);int ans=0;for(int i=1;i<=n;i++) cin>>a[i];bool ok=1;for(int i=1;i<=n;i++){if(!a[i] && ok){int j=i;while(j<=n && !a[j] && j-i+1<k) j++;i=j;if(j>n || a[j]) continue;ans++;ok=0;}else{ok=1;}}cout<<ans<<'\n';
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int T=1;cin>>T;while(T--){solve();}return 0;
}
C. I Will Definitely Make It
记录当前高度为dep,我们一定是不断往高处走,所以对塔楼从小到大排序,从题目指定的塔楼开始往上爬。
记录当前所在塔楼高度为now,如果下一个要攀登的塔楼a[i].va[i].va[i].v与nownownow的差值即需要花费的时间小于等于nownownow与depdepdep即水上升到当前高度nownownow的时间,那么就可以继续爬,否则就结束。
详情看代码。
#include<bits/stdc++.h>
#define LL long long
using namespace std;typedef pair<int,int> PII;
const int N=1e5+10;
struct node{int v,id;bool operator<(const node&t) const {return v<t.v;}
}a[N];
void solve(){int n,k;cin>>n>>k;int mx=0;for(int i=1;i<=n;i++){cin>>a[i].v;a[i].id=i;mx=max(mx,a[i].v);}sort(a+1,a+n+1);int pos=-1;for(int i=1;i<=n;i++){if(a[i].id==k){pos=i;break;}}int now=a[pos].v;int dep=0;
// cout<<now<<' '<<a[pos+1].v<<' '<<dep<<'\n';for(int i=pos+1;i<=n;i++){if(a[i].v==now) continue;if(a[i].v-now+dep<=now){dep+=a[i].v-now;now=a[i].v;}else{cout<<"NO"<<'\n';return ;}}if(now==mx) cout<<"YES"<<'\n';else cout<<"NO"<<'\n';
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int T=1;cin>>T;while(T--){solve();}return 0;
}
D. This Is the Last Time
主要到reali<=rireal_i <= r_ireali<=ri,那么只能是不断变大的,假设存在val′<valval'<valval′<val,且有li<=val′<=ril_i<=val'<=r_ili<=val′<=ri
同时reali>valreal_i>valreali>val,那么能推出li<=val<=ril_i<=val<=r_ili<=val<=ri
所以按照左端点从小到大排序,遍历的时候reali<valreal_i<valreali<val的都不用考虑
#include<bits/stdc++.h>
#define LL long long
using namespace std;typedef pair<int,int> PII;
const int N=1e5+10;
struct node{int l,r,real;bool operator<(const node&t)const{if(l==t.l){if(r==t.r) return real<t.real;else return r<t.r;}return l<t.l;}
}a[N];
void solve(){int n,k;cin>>n>>k;
// priority_queue<node,vector<node>,greater<node>> q;for(int i=1;i<=n;i++){cin>>a[i].l>>a[i].r>>a[i].real;}sort(a+1,a+n+1);int ans=k;for(int i=1;i<=n;i++){if(ans>=a[i].l && ans<=a[i].r && ans<a[i].real) ans=a[i].real;}cout<<ans<<'\n';
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int T=1;cin>>T;while(T--){solve();}return 0;
}
E. G-C-D, Unlucky!
首先得满足一些容易想到的规则:
- p[n]=s[1]p[n]=s[1]p[n]=s[1]
- p数组满足不增,s数组满足不减
- $p[i]%p[i+1]=0,s[i]%s[i-1]=0 $
这些满足的情况下,尝试构造数组满足a[i]=lcm(p[i],s[i])a[i]=lcm(p[i],s[i])a[i]=lcm(p[i],s[i]),至于为什么是最小公倍数,说实话是凭直觉猜的,在满足都是p[i],s[i]p[i],s[i]p[i],s[i]的倍数情况下觉得数越小越好,越容易满足条件。
#include<bits/stdc++.h>
#define int long long
using namespace std;typedef pair<int,int> PII;
const int N=1e5+10;
int a[N];
void solve(){int n;cin>>n;vector<int> p(n+1),s(n+1);for(int i=1;i<=n;i++) cin>>p[i];for(int i=1;i<=n;i++) cin>>s[i];for(int i=1;i<n;i++){if(p[i+1]>p[i] || ((p[i]%p[i+1])!=0)){cout<<"NO"<<'\n';return ;}}for(int i=n;i>1;i--){if(s[i-1]>s[i] || ((s[i]%s[i-1])!=0)){cout<<"NO"<<'\n';return ;}}if(s[1]!=p[n]){cout<<"NO"<<'\n';return ;}a[1]=p[1],a[n]=s[n];for(int i=2;i<n;i++){int x=p[i],y=s[i];int z=x*y/__gcd(x,y);a[i]=z;}int gcd=0;for(int i=1;i<=n;i++){gcd=__gcd(gcd,a[i]);if(gcd!=p[i]){cout<<"NO"<<'\n';return ;}}gcd=0;for(int i=n;i>=1;i--){gcd=__gcd(gcd,a[i]);if(gcd!=s[i]){cout<<"NO"<<'\n';return ;}}cout<<"YES"<<'\n';
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int T=1;cin>>T;while(T--){solve();}return 0;
}
F. 1-1-1, Free Tree!
dfs用map维护每个节点的儿子所有不同颜色的花费总和,修改某个点颜色的时候单独对其父亲讨论一下,改其map,然后儿子就直接用map进行加减
详情看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;typedef pair<int,int> PII;
const int N=2e5+10;
int n,q,a[N],fa[N],c[N];
map<int,int> mp[N];
vector<PII> g[N];
int ans;
void dfs(int u) {for(auto [v,w]:g[u]) {if(v==fa[u]) continue;if(a[v]!=a[u]) {ans+=w;}fa[v]=u;c[v]=w;mp[u][a[v]]+=w;dfs(v);}
}
void solve() {cin>>n>>q;ans=0;for(int i=1; i<=n; i++) {fa[i]=-1,g[i].clear(),mp[i].clear(),c[i]=0;}for(int i=1;i<=n;i++) cin>>a[i];for(int i=1; i<=n-1; i++) {int u,v,w;cin>>u>>v>>w;g[u].push_back({v,w});g[v].push_back({u,w});}dfs(1);while(q--) {int u,x;cin>>u>>x;if(a[u]==x) {cout<<ans<<'\n';continue;}if(fa[u]!=-1) {if(a[u]==a[fa[u]]) ans+=c[u];if(x==a[fa[u]]) ans-=c[u];mp[fa[u]][a[u]]-=c[u];mp[fa[u]][x]+=c[u];}if(mp[u].count(a[u])) ans+=mp[u][a[u]];if(mp[u].count(x)) ans-=mp[u][x];a[u]=x;cout<<ans<<'\n';}
}signed main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int T=1;cin>>T;while(T--) {solve();}return 0;
}
G1. Big Wins! (easy version)
待补…