B:关鸡 ---->最让我难受的一题,想法对但不知道怎么实现
做法:仔细思考后我们能够想到答案是<=3的,因为我们可以直接把它关在起点只花费三,(有个特别妙的代码在状态中看到的(笑他的做法是:把整个区间分为两段l,r,用map存,每输入一个点就去枚举它四周(有贡献的点)就是-->与它的对面的行能用3-x来表示和y-1,y+1,y与它的本身的和,只要>=2就可以后鸡的某一边封住,然后去判断(2,0)这个点,去看是不是花费更加的低,这里用到 了 max(p[1,-1],l/2) 和 max(p[1,1],r/2) 因为l和r最大是2这里就是判断对应的某一边何去封才花费小
#include<iostream>
#include<map>
using namespace std;
void solve()
{
map<int,int>p[3];
int l=0,r=0;//代表左右是否能关上坤
int q;cin>>q;
while(q--)
{
int x,y;
cin>>x>>y;
p[x][y]++;
if(y>0)//在坤的右边
{
r=max(r,p[x][y]+p[3-x][y-1]+p[3-x][y+1]+p[3-x][y]);//加上周围点太妙了
}
if(y<0)//在坤的左边
{
l=max(l,p[x][y]+p[3-x][y-1]+p[3-x][y+1]+p[3-x][y]);
}
}
if(r>2)r=2;//2就够用
if(l>2)l=2;
int ans=4-l-r;
int res=3-max(p[1][-1],l/2)-max(p[1][1],r/2)-p[2][0];
ans=min(ans,res);
cout<<ans<<endl;
}
int main()
{
int T;cin>>T;
while(T--)solve();
}
C题:按闹分配----->大意有n个人在排序办事,每个的办事花费时间为ti,定义了一个容忍度为每一个办完他自己的事之后花的时间Di,定义所以有的容忍度为S=(求和)Di;而相关已经合理安排了每个人的办事顺序使S最小。现在有一只坤坤要办急事,它可以让办事人员立刻放下手中的事来帮它办事,坤坤办事花费的时间为tc;假设坤坤插队后的最小容忍度变为Sc,若Sc-Smin>=M,则办事人员让坤坤插队,否则不可以,M为办事人员的容忍度
做法:这是一道贪心+二分的题,先贪心的让Smin先为最小,即排序让花费时间最少的先办事,前缀和再相加就是总Smin然后去二分插队位置,求Sc=Smin+tc*(n-mid+1)改变l和r就行
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
long long a[N],s[N];
int main()
{
int n,q,need;
cin>>n>>q>>need;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
long long alls=0;
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+a[i];
alls+=s[i];
}
while(q--)
{
long long st;
cin>>st;
long long l=0,r=n+1;
while(l+1<r)
{
long long mid=l+r>>1;
long long sc=alls+need*(n-mid+1);
if(sc-alls<=st)r=mid;
else l=mid;
}
cout<<s[l]+need<<endl;
}
return 0;
}
题目E:本题又主要考察贪心了------>题意:对n只坤,初始都有分,还有场战斗,两只坤相斗,win的加3分,输的不减,或者平局都各加1分,让你控制赢或平局,使得一号坤的排名尽量向前
做法:太坑了这一题,乍一看还真像一道贪心题,再一看题目唉~贪心,可是比赛的时间老是能想到hack的数据(都想睡着了。其实这不是一道贪心,就是一道dfs,因为数据量小哎哎~
#include<iostream>
using namespace std;
const int N = 110;
int f[N],v[N],u[N];
int n,m;
int ans;
void dfs(int match)
{
if(match>m)
{
int k=1;
for(int i=2;i<=n;i++)
if(f[i]>f[1])k++;
ans=min(ans,k);
return;
}
f[v[match]]+=3;
dfs(match+1);
f[v[match]]-=3;
f[u[match]]+=3;
dfs(match+1);
f[u[match]]-=3;
f[v[match]]++;
f[u[match]]++;
dfs(match+1);
f[v[match]]--;
f[u[match]]--;
}
int main()
{
int T;cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>f[i];
for(int i=1;i<=m;i++)cin>>v[i]>>u[i];
ans=n;
dfs(1);
cout<<ans<<endl;
}
return 0;
}
题目G:why买外卖---->鸡很饿,鸡要吃外卖,今天点份炸鸡外卖!
鸡使用的外卖程序有若干个满减优惠,第i个优惠可以表示为"满a[i]元减b[i]元",多个满减优惠可以叠加。
满减的具体结算流程是:假设鸡购买的食物原价共为x元,则所有满足x≥a[i]的满减优惠都可以一起同时被使用,优惠后价格记为y,则鸡只要支付y元就可以了(若y≤0则不需要支付)。
现在,鸡的手机里一共只有m元钱,鸡想知道,他所购买的食物原价x最多为多少。
做法:去贪心地从面值小的枚举,如果那个哎呀不知道怎么説了直接上代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
pair<int,int>a[N];
int main()
{
int T;cin>>T;
while(T--)
{
long long q,now;
long long sum=0;
cin>>q>>now;
for(int i=1;i<=q;i++)
{
long long x,y;
cin>>x>>y;
a[i].first=x;
a[i].second=y;
}
sort(a+1,a+1+q);
long long ans=0;
bool flag=0;
for(int i=1;i<=q;i++)
{
sum+=a[i].second;
if(sum+now>=a[i].first)
{
flag=1;
ans=max(ans,sum+now);
}
}
if(flag==1)cout<<ans<<endl;
else cout<<now<<endl;
}
return 0;
}
题目L:要有光
#include<iostream>
using namespace std;
int main()
{
int T;cin>>T;
while(T--)
{
int c,d,h,w;
cin>>c>>d>>h>>w;
cout<<(2*w+4*w)*c/2<<endl;
}
return 0;
}