A.拯救咕咕咕之史莱姆
Solution
按题意来,手算:
DAAAAAMN!
AOLIGEI!
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e6 + 5;
ll n;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n&&n){
if(n>75) cout<<"DAAAAAMN!\n";
else cout<<"AOLIGEI!\n";
}
return 0;
}B.烦人的依赖
Solution
sort+映射+优先队列拓扑排序
拓扑排序模板题。
和普通的拓扑排序不同的点在于,这里给出的string,且字典序小的具有优先级。
优先级?嗯哼想到了什么?我们的老朋友优先队列!
- 这里需要预处理字符串的时候,先进字符串进行排序,再用unordered_map对其进行映射。
- 利用映射之后的值(数字)对其进行拓扑排序,普通的拓扑序用queue即可,而这道题目有个字典序小的优先的要求,所以我们要用priority_queue(优先队列)去拓扑。
- 若成环则"Impossible!";
输出拓扑序。
tips:多组数据注意初始化(补题WA了一发
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 3e4 + 5;
int n,m;
string s[N];
vector<int> G[N];
unordered_map<string,int> id;
int in[N],a[N],cnt;
void topsort(){
priority_queue<int>q;
for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
while(q.size()){
int p=q.top();q.pop();
a[++cnt]=p;
for(auto c:G[p]) if(!--in[c]) q.push(c);
}
}
void solve(int x){
cin>>n>>m;
id.clear();
cnt=0;
for(int i=1;i<=n;i++) G[i].clear(),in[i]=0;
for(int i=1;i<=n;i++) cin>>s[i];
sort(s+1,s+1+n,greater<string>());
for(int i=1;i<=n;i++) id[s[i]]=i;
for(int i=1;i<=m;i++){
string u,v;
cin>>u>>v;
++in[id[v]];
G[id[u]].push_back(id[v]);
}
topsort();
cout<<"Case #"<<x<<":"<<'\n';
if(cnt!=n) cout<<"Impossible\n";
else{
for(int i=1;i<=n;i++) cout<<s[a[i]]<<'\n';
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
for(int i=1;i<=T;i++) solve(i);
return 0;
}C.异或生成树
Solution
树形DP
设表示以
为根能否组成
。
- 用临时变量
保存
- 更新
- 更新答案
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 2e2 + 5;
int n,a[N],ans;
bool f[N][N];
bool s[N];
vector<int> G[N];
void dfs(int x,int fa){
f[x][a[x]]=true;
for(auto c:G[x]){
if(c==fa) continue;
dfs(c,x);
memset(s,false,sizeof(s));
for(int i=0;i<=127;i++)
for(int j=0;j<=127;j++)
s[i^j]|=f[x][i]&&f[c][j];
for(int i=0;i<=127;i++)
f[x][i]|=s[i];
}
for(int i=1;i<=127;i++)
if(f[x][i]) ans=max(ans,i);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
cout<<ans;
return 0;
}E.无敌阿姨
Solution
纯模拟
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e2 + 5;
int n,m,k,a[N];
void solve(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++) cin>>a[i];
int hp=m;
int ans=1;
for(int i=1;i<=n;){
if(hp>a[i]){
hp-=a[i];
a[i]=0;
if(hp<=k && i<n) hp=m,ans++;
if(hp<m && hp>k && i<n) hp-=k;
i++;
}else if(hp<a[i]){
a[i]-=hp;
hp=m;
ans++;
}else{
a[i]-=hp;
hp=m;
if(a[n]!=0) ans++;
i++;
}
if(a[n]==0) break;
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
while(T--) solve();
return 0;
}
G.校车
Solution
利用set唯一性记录站点数量
利用差分纪录最大座位数量
由于我是直接遍历set,所以不需要离散化。
Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e5 + 5;
int n;
void solve(){
cin>>n;
set<int>s;
unordered_map<int,int> M;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
M[x]++;M[y]--;
s.insert(x);
s.insert(y);
}
int ans=1;
int tmp=0;
for(auto c:s){
M[c]+=tmp;
ans=max(ans,M[c]);
tmp=M[c];
}
cout<<s.size()<<" "<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
while(T--){
solve();
}
return 0;
}H.中位数
Solution
这道题就是先求出,再算个前缀和预处理,没次输出答案即可。
问题在于如何求出?
的因子一定成对分布在
的左右两侧
的中位数因子,一定
- 我们记录最大的
的中位数因子在
中,后续
- 求前缀和记录答案
Code
#include <iostream>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e6 + 5;
ll pre[N],f[N];
void init(){
ll cnt=0;
for(int i=1;i<N;i++)
for(int j=i;j<N;j+=i){
if(1ll*i*i<=j) f[j]=i;
}
for(int i=1;i<N;i++) f[i]=(f[i]+i/f[i])/2;
for(int i=1;i<N;i++) pre[i]=(pre[i-1]+f[i])%mod;
}
void solve(){
ll x;
cin>>x;
cout<<pre[x]<<'\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
init();
while(T--) solve();
return 0;
}体验
感觉参赛体验挺差的,D题应该没那么简单,但是一开始却看大家n^2做法暴力随便过,我一直在思考nlogn的写法,也没思考出什么结果,后来重判都WA了。歪榜浪费了不少时间,然后G题很简单的差分题,然后第一遍就AC的,由于他数据错了,怎么改都是WA,又浪费了不少时间,这也是由于我自己经验不足吧,心态也有点崩,大家都过了E,然后我G也不知道WA到哪儿,然后写E的时候很菜的WA了7发才过,有一行代码上下顺序不对。
怎么说呢,这些杂七杂八的因素不应该成为对自己的干扰,还是要保持冷静、理智的头脑去解题吧。

京公网安备 11010502036488号