A Minutes Before the New Year
不用写循环,直接用减去当前分钟数就行了
T = int(input())
for kase in range(T):
h, m = [int(x) for x in input().split()]
print(1440-h*60-m)
B Candies Division
T = int(input())
for kase in range(T):
n, k = [int(x) for x in input().split()]
ans = n//k*k
ans += min(n%k,k//2)
print(ans)
C Friends and Gifts
这题是要在给定的图上连一些边使其形成一个置换,且
先统计一下入度,剩下的边必须连到入读为的点上去
先给那些既没有入度也没有出度的点安排出度,这样是为了防止最后出现他不得不连自己的情况,搞一个双端队列就可以维护了。
然后再安排剩下的就好了
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
ll f[maxn], n, ok[maxn];
deque<ll> q;
int main()
{
ll i;
n=read();
rep(i,n)f[i]=read(), ok[f[i]]=1;
rep(i,n)if(!ok[i])q.emb(i);
rep(i,n)if(!f[i] and !ok[i])
{
if(q.front()!=i){f[i]=q.front(); q.pop_front();}
else {f[i]=q.back(); q.pop_back();}
}
rep(i,n)if(!f[i])
{
if(q.front()!=i){f[i]=q.front(); q.pop_front();}
else {f[i]=q.back(); q.pop_back();}
}
rep(i,n)printf("%lld ",f[i]);
return 0;
}
D Christmas Trees
一个题
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
priority_queue<pll,vector<pll>,greater<pll>> heap;
set<ll> used;
ll n, m;
vector<ll> ans;
bool in(ll x){return used.find(x)!=used.end();}
void ins(ll pos, ll step){if(!in(pos)) { heap.em( pll(step,pos) ); used.em(pos); } }
ll a[maxn];
int main()
{
ll i, j, tot=0;
n=read(), m=read();
rep(i,n)used.em(a[i]=read());
rep(i,n)ins(a[i]-1,1),ins(a[i]+1,1);
while(m--)
{
auto pr=heap.top(); heap.pop();
auto pos=pr.second, step=pr.first;
tot += pr.first;
ans.emb(pos);
ins(pos-1,step+1);
ins(pos+1,step+1);
}
printf("%lld\n",tot);
for(auto x:ans)printf("%lld ",x);
return 0;
}
E New Year Parties
这题好
对于最小值,想法肯定是尽量去“缩”,能合并的就合并。令表示处有多少个人,我从小到大枚举,当我发现第一个时,我就把的人都赶到去,这样肯定不会更劣嘛,而且增加了与右边的人的接触机会。当我这样决策时,其实就认定了必定有人,那么既然这里已经有人了,我就破罐子破摔,右边有人的话让他也过来,就这样贪心下去…得到最小的答案
对于最大值,想法是尽量去“扩”,我先从左往右扫,让那些能放一个人去左边的就放一个人去左边。然后再反过来,从右往左扫,让能去右边的就去右边。
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
ll n, a[maxn], b[maxn];
int main()
{
ll i, ans1=0, ans2=0, len;
n=read();
rep(i,n)a[read()]++;
rep(i,n)b[i]=a[i];
len=0;
rep(i,n)if(a[i])
{
ans1++;
i++;
if(a[i+1])i++;
}
printf("%lld ",ans1);
for(i=0;i<=n;i++)if(b[i]==0 and b[i+1])b[i]++, b[i+1]--;
for(i=n+1;i;i--)if(b[i]==0 and b[i-1])b[i]++, b[i-1]--;
for(i=0;i<=n+1;i++)ans2+=!!b[i];
printf("%lld",ans2);
return 0;
}
F DIY Garland
点到父亲的连边的权值是+所有到儿子的边的权值,所以到父亲的这条边必然在子树中的边之前出现,再者,最开始走的边肯定都是带有,直到我走完了所有带有的边,才会去走,看起来就是不停的走一些链。
走完一条链走下一条链,当且仅当我已经走到了当前最大的数字。所以出现重复元素,就说明上次走过去的那条边的末端是目前没出现的最大的数字。
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
vector<ll> v;
set<ll> s;
vector<pll> ans;
ll n, a[maxn], p;
bool used(ll x){return s.find(x)!=s.end();}
int no(){printf("-1");return 0;}
int main()
{
ll i, r;
n=read();
rep(i,n-1)a[i]=read();
rep(i,n)v.emb(i);
rep(i,n-1)
{
ll x=a[i];
if(used(x))
{
while(!v.empty() and used(v.back()))v.pop_back();
if(v.empty())return no();
auto t=v.back(); v.pop_back();
s.em(t);
ans.emb( pll(t,p) );
}
else
{
if(p)ans.emb( pll(p,x) );
else r=x;
s.em(x);
}
p=x;
}
while(!v.empty() and used(v.back()))v.pop_back();
if(v.empty())return no();
ans.emb( pll(v.back(),p) ); v.pop_back();
while(!v.empty() and used(v.back()))v.pop_back();
if(!v.empty())return no();
printf("%lld\n",r);
for(auto pr:ans)printf("%lld %lld\n",pr.first,pr.second);
return 0;
}
来源:CSDN
作者:*ACoder*
链接:https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/103952011