Codeforcesラウンド#611Div3解決レポート
A.分正月前に
- 直接シミュレーション
#include<bits/stdc++.h>
#define PII pair<int, int>
using namespace std;
typedef long long ll;
int T, n;
void solve()
{
int h, m;
cin >> h >> m;
int ans = 0;
ans += (24 - h - 1) * 60;
ans += (60 - m);
cout << ans << endl;
}
int main()
{
scanf("%d", &T);
while(T--) solve();
return 0;
}
B.キャンディーズ課
- 二等分する最適なソリューションを超える、リガに貪欲出て行くのです。
#include<bits/stdc++.h>
#define PII pair<int, int>
using namespace std;
typedef long long ll;
int T, n, k;
void solve()
{
cin >> n >> k;
if(n%k == 0){
cout << n << endl;
return;
}
int a = n / k; //每个人a个糖
int b = n % k;
if(b <= k / 2) cout << a*k+b << endl;
else cout << a*k + k / 2 << endl;
}
int main()
{
scanf("%d", &T);
while(T--) solve();
return 0;
}
C.友人とギフト
- 実際には、その意図は、あなたが0の場所の順序で話題の番号を記入しましょう、とシーケンスは順列として得られ、対応する番号が対応する位置に表示することはできませんようにすることです。
- 唯一のライン上に逆王Litou塗りつぶした後、ノーショーのどのようなデジタル記録を見てする必要があります。
- 実施例50 024 1と3が発生していなかった、そして後方塗りは53124です。
- しかし、場所と数字が一致状況があること、登場していることが、\(A(I)== I \)が、逆に、そして唯一のそのような状況での位置が記入します、プラス2が表示される場合もありますゼロはちょうど罰金を交換します。
#include<bits/stdc++.h>
#define PII pair<int, int>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
int n, a[maxn];
int vis[maxn];
vector<int> z;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
vis[a[i]] = 1;
if(a[i] == 0) z.push_back(i);
}
int cnt = 1;
for(int i = n; i >= 1; i--)
{
if(a[i]) continue;
while(vis[cnt]) cnt++;
a[i] = cnt; vis[cnt] = 1;
}
for(int i = 0; i < z.size(); i++)
{
int num = z[i];
if(a[num] == num)
{
if(i < z.size()-1) swap(a[num], a[z[i+1]]);
else swap(a[num], a[z[i-1]]);
break;
}
}
for(int i = 1; i <= n; i++)
printf("%d ", a[i]);
return 0;
}
D.クリスマスツリー
- 貪欲。
- まず、両サイドには、クリスマスツリーの上に配置する必要があります最良の選択です。
- キュー内の位置に入りました。
- その後、ポイントトラバース同様のBFSを考えることができます。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
queue<int> q;
map<int, int> mp;
int n, m;
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for(int i = 1, x; i <= n; i++)
{
cin >> x;
q.push(x); mp[x] = 0;
}
long long res = 0;
vector<int> ans;
while(m)
{
int p = q.front(); q.pop();
if(!mp.count(p-1))
{
q.push(p-1);
mp[p-1] = mp[p]+1;
}
if(!mp.count(p+1))
{
q.push(p+1);
mp[p+1] = mp[p]+1;
}
if(mp[p] > 0)
{
ans.push_back(p);
res += mp[p];
m--;
}
}
cout << res << endl;
for(auto x : ans)
cout << x << " ";
puts("");
return 0;
}
E.新年パーティー
- 私のコードのタイトルは醜いですが、また、より良い理解します。
- 実際には、長いライン上の貪欲動くほど。
- 最小:
- 誰か上の位置ならば、私は1つの位置に移動しました。
- 他の誰かの横位置ならば、私は次の位置に移動され、この位置はもはや移動することができます。
- 次の場所が、誰が次の位置にあった場合、彼らは中央の位置に合わせて移動することができます。
- 最大:
- 場所は三人を持っている場合、それは三つの位置を占めていました。
- 二人、および位置の場所の後に占められていない、以前と現在位置、現在位置の職業上の1、それ以外の場合。
- 一人だけならば、人々は駅の前と後の状況を見てください。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
int a[maxn], n;
int vis[maxn];
int vis1[maxn];
int vis2[maxn];
bool mi[maxn];
void get_min()
{
for(int i = 1; i <= n; i++)
{
if(vis1[i] && !mi[i])
{
if(vis1[i-1])
{
vis1[i-1] += vis1[i];
vis1[i] = 0;
mi[i-1] = 1;
}
else if(vis1[i+1])
{
vis1[i+1] += vis1[i];
vis1[i] = 0;
mi[i+1] = 1;
}
else if(vis1[i+2] && !mi[i+2])
{
vis1[i+1] += vis1[i+2];
vis1[i+1] += vis1[i];
vis1[i] = vis1[i+2] = 0;
mi[i+1] = mi[i] = mi[i+2] = 1;
}
}
} int ans = 0;
for(int i = 0; i <= n+1; i++)
if(vis1[i]) ans++;
cout << ans << " ";
}
void get_max()
{
for(int i = 1; i <= n; i++)
{
if(vis[i])
{
int num = vis[i];
if(num >= 3)
{
vis2[i-1]++;
vis2[i]++;
vis2[i+1]++;
}
else if(num == 2)
{
//如果上一个位置没有放
if(!vis2[i-1])
{
vis2[i-1]++;
vis2[i]++;
}
else {
vis2[i]++;
vis2[i+1]++;
}
}
else if(num == 1)
{
if(!vis2[i-1]) vis2[i-1]++;
else if(!vis2[i]) vis2[i]++;
else vis2[i+1]++;
}
}
}
int ans = 0;
for(int i = 0; i <= n+1; i++)
if(vis2[i]) ans++;
cout << ans << endl;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
vis[a[i]]++;
vis1[a[i]]++;
}
get_min();
get_max();
return 0;
}
F. DIYガーランド
問題の意味の説明
- 所与の(N-1 \)\ラインと\(N- \)ランタン。
すべての電気が来ていたから、光源ランプは、あります。
- 2つのランプとの結線は、各ランプは、それ自身の数、輝度有する\(2 ^ Iを\) 。
- 光は、補助光に、主からメインとサブ光ランプ、ランプ電力に分割されます。
- ワイヤを切断した後、各電線の重要度は通電と輝度にすることはできません。
重要所与ワイヤの降順に\(N-1 \)は、各ランプに接続された数つの出力線を下るようにメイン光は、ライン番号。
思考
- グッド面倒な質問が直面しています...
- 最初の\(N-1 \)ラインと\(N- \)ランタン、決定することができ、これはツリー構造です。
- ワイヤの重要性は、光源ランプ肯定最大を連結するためのトピックの重要性は、ランプ配線のノードに応じて与えられ、その後、第一光源は、避けられません。
- 第二に、リーフノードは間違いなくメイン光ではない、と我々は、サブツリーのリーフノードのサイズが0であることを知っています。(で\(゜\)配列レコードサブツリーのサイズ)
- 我々は最初のプライオリティキューに押し込ますべてのリーフノードを見つけることができますので、その後、逆メインライトを接続します。(そのため、ワイヤの重要性について降順)。
- 全体として、それを接続した後ので、ランプのサブツリーの大きさを低減することができます。
- メイン光保存サブツリーのサイズが0の場合、それはリーフノードとなり、キューに入れられた;ので、際限のツリーが形成されるまで。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int deg[maxn], n, rt;
vector<int> main_lamp;
int main()
{
scanf("%d", &n);
scanf("%d", &rt);
deg[rt]++;
main_lamp.push_back(rt);
for(int i = 2, x; i <= n - 1; i++)
{
scanf("%d", &x);
deg[x]++;
main_lamp.push_back(x);
}
priority_queue<int, vector<int>, greater<int> > q;
for(int i = 1; i <= n; i++)
if(deg[i] == 0) q.push(i);
vector<pair<int, int> > ans;
while(q.size())
{
int x = q.top();
q.pop();
int y = main_lamp[main_lamp.size()-1];
main_lamp.pop_back();
ans.push_back(make_pair(y, x));
if(ans.size() == n - 1) break;
deg[y]--;
if(deg[y] == 0) q.push(y);
}
cout << rt << endl;
for(int i = ans.size()-1; i >= 0; i--)
cout << ans[i].first << " " << ans[i].second << endl;
return 0;
}