A
题意:
给每个房间装暖气,对于每个房间,给出两个数,第一个为该房间可装暖气个数,第二个为需要的暖气片个数,当一个暖气包括n个暖气片时,制作成本为n^2,问一个房间最低成本使得满足要求
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define N 200001
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
int main()
{
std::ios::sync_with_stdio(false);
// freopen("E:\\in.txt","r",stdin);
int k;
cin>>k;
while(k--)
{
int a,b;
cin>>a>>b;
if(a>=b)cout<<b<<endl;
else
{ int sum;
int x=b/a;
int y=b%a;
int n=a-y;
sum=(x+1)*(x+1)*y+x*x*n;
cout<<sum<<endl;
}
}
}
思路:
使一个房间内的每个暖气所含有的暖气片个数尽可能平均
B
题意:给两个数,一个数减任意x,则另一个数同时减2x,可以重复任意次,问两个数是否可以同时变成0
思路:
经过一次操作使两个数相同,然后看得到的这个数是否可以被3整除就完事了
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define N 200001
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
int main()
{
std::ios::sync_with_stdio(false);
// freopen("E:\\in.txt","r",stdin);
int k;
cin>>k;
while(k--)
{
ll a,b;
cin>>a>>b;
if(a<b)
{ll temp;
temp=a;
a=b;
b=temp;
}
if(a>2*b)
{
cout<<"NO"<<endl;
continue;
}
ll x=a-b;
a=a-2*x;
if(a%3==0)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
C
题意:
现有10^100块木板需要涂漆,第x块如果是x是r的倍数,则涂一种颜色,是b的倍数,则涂另一种颜色。如果既是r又是b的倍数,那么两种颜色都可以涂;如果连续有k块板的颜色是一样的,则输出REBEL,否则输出OBEY。问是否能避免被处死
思路:
找规律最后发现能使一个颜色连续最多的的时候是。。。
不好说,举个例子。。。
假设篮(大的数)红(小的数)
篮红…………………篮(红)这样的情况,夹在中间的红色(小的数)连续的最多。然后就可以推出公式
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define N 200001
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
int main()
{
std::ios::sync_with_stdio(false);
//freopen("E:\\in.txt","r",stdin);
int k;
cin>>k;
while(k--)
{
ll a,b,c;
cin>>a>>b>>c;
int t=__gcd(a,b);//这一步可以把大数变小
a/=t,b/=t;
if(a<b)
{
ll temp=a;
a=b;
b=temp;
}
if((a-2)/b+1>=c)cout<<"REBEL"<<endl;
else cout<<"OBEY"<<endl;
}
}
D
不会做。。。
当时读题的时候费老大的劲,一遍没读明白,但感觉应该很难,想着怎么也得把题读懂了再看看会不会啊,结果不会,发晕,属于一点想法都没有的难题。
题意:有m个士兵,t秒,你要带尽可能多的士兵从0去n+1,且他们不能被杀死。路上有一些陷阱,陷阱d[i]会杀死能力比它小的士兵,陷阱位置在l[i],当你走到r[i]时可以拆除它。每次你可以向左或者向右移动。自己不会被陷阱杀死,可以先去把陷阱拆除再回来带兵。
思路:
贪心,二分,差分
对士兵从大到小排序后用二分查找满足条件的最弱的的士兵,怎么判断呢?
就看把当前士兵带过去所花的最短时间是否小于规定时间,如果小于,则就是他了。比他强的士兵都可以带过去。题解用到了差分,没学过,就去找的资料,差分前缀和用到这里太精秒了
题解
奇怪的知识又增加了:差分资料
E
题意:
现在有n个人打拳,序号小的打不过序号大的,并且如果你花ai元贿赂第i个人,你就能赢。你朋友参加了比赛,你可以分配每次比赛的组队以及贿赂,问你最少需要多少钱。
解法:如果你不贿赂要是第一,那么你只能是第n个人,如果不贿赂进二强,那么你必须是第n/2到第n个人。如果进入4强,那么必须是第n/4到第n个,这样递归下去。
那么你就能知道你朋友是第几强,如果还要往上,那么就要贿赂能够进下一场比赛中的一个即可,所以是贿赂用钱最少的那个。那么只需要每次判断是否是2的幂次,如果是,那么就是要在之后的人中至少要贿赂一个
代码:
这代码简直是艺术
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
ll a[N];
multiset<ll>s;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
ll ans=0;
for(int i=n;a[i]!=-1;i--)
{
s.insert(a[i]);
if(!(i&(i-1)))//i&(i−1)的作用是将i的二进制表示中的最低位为 1的改为0。而且如果i是二的次幂的话返回0。
{
ans+=*s.begin();
s.erase(s.begin());
}
}
printf("%lld",ans);
return 0;
}
F
题意:
给你一棵树,每个结点的颜色可能是[li,ri]任一颜色,求所有可能的树的树价值总和。每棵树的价值表示所有颜色相同的两点间的距离总和。