ICPC网络预选赛(第二场)(一)
文章目录
题目链接
F Tourist
题目大意
初始值为sum=1500,接下来会有n个回合,每个回合sum+=a_i,求出sum>=4000的回合,如果没有找到这样的回合返回-1
题解思维
签到题,按着题目大意来即可
解题代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int main()
{
int n;
ll sum = 1500;
cin>>n;
ll t;
for(int i=1;i<=n;i++)
{
cin>>t;
sum+=t;
if(sum>=4000)
{
cout<<i<<"\n";
return 0;
}
}
cout<<-1<<"\n";
return 0;
}
J Stacking of Goods
题目大意
将一堆物品竖着一个个堆叠起来,求出被压缩后最小的体积。
题解思维
采用贪心的策略,由于我们希望将体重大的物体放在最上面,压缩率大的物体放在最下面。
不妨将每个物体的
c
i
/
w
i
当作被希望放在最下面的权重,
c
越大起正向影响,
w
越大起负向影响。
不妨将每个物体的c_i/w_i当作被希望放在最下面的权重,c越大起正向影响,w越大起负向影响。
不妨将每个物体的ci/wi当作被希望放在最下面的权重,c越大起正向影响,w越大起负向影响。
由此将物体进行排序后,根据顺序,将物体一个个堆叠即可
解题代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Good {
long long weight;
long long volume;
long long compression;
Good(long long w, long long v, long long c) : weight(w), volume(v), compression(c) {}
};
// 比较器,用于按照ci/wi排序 考虑到浮点数的影响
bool compare(const Good& a, const Good& b) {
return a.compression * b.weight < b.compression * a.weight;
}
int main() {
int n;
cin >> n;
vector<Good> goods;
for (int i = 0; i < n; ++i) {
long long w, v, c;
cin >> w >> v >> c;
goods.emplace_back(w, v, c);
}
// 按照压缩系数与重量的比值排序
sort(goods.begin(), goods.end(), compare);
long long totalWeight = 0;
long long totalVolume = 0;
// 计算总的实际体积
for (const auto& good : goods) {
totalVolume += good.volume - good.compression * totalWeight;
totalWeight += good.weight;
}
cout << totalVolume << endl;
return 0;
}
/*
3
1 8 1
2 9 2
3 10 2
*/
I Strange Binary
题目大意
尝试找到能按特定规律组合的a_i使得=n
解题思维
考虑到相邻的两个bit位,大位是小位的两倍,根据这个性质来解题
#include<bits/stdc++.h>
using namespace std;
using uint = unsigned int;
void solve()
{
//首先读取要求的数
uint n;
cin>>n;
vector<int> res(31);
//得到每个位
for(int i=31;i>=0;i--)res[i] = (n>>i)&1;
//当前者与后者满足1,0关系时,采用上面的性质,进行等价替换
for(int i=0;i<31;i++)if(res[i]==1&&res[i+1]==0)res[i]=-1,res[i+1]=1;
bool find = 0;
//如果还有连续的两个00说明,表明该数不能生成满足条件的序列。
for(int i=0;i<31;++i)if(res[i]==0&&res[i+1]==0) find =1;
if(find)cout<<"NO\n";
else
{
cout<<"YES\n";
for(int i=1;i<=4;++i){
for(int j=0;j<8;++j){
cout<<res[(i-1)*8+j]<<' ';
}
cout<<'\n';
}
}
}
int main()
{
int t;
cin>>t;
while(t--) solve();
}
A Gambling on Choosing Regionals
题目大意
本题目的含义就是,有多场比赛,且对每个学校有限制名额,每个队只能参加两次,实力值高的队伍排名高,现在要我们求出最坏情况下,每个队的最小排名。
题解思维
什么是最坏情况,当然就是你参加比赛的时候,你之前所有的强队都在【也就是要保证这个队伍存在,且给它匹配高手】。那怎么得到最小排名呢【也就是参加比赛参加的人数越少那么自然的排名也就越小】 排名越小指的就是排名越好,实力最强排1,实力次强排2,1<2,更小的排名意味着更好。
解题代码
#include<bits/stdc++.h>
using namespace std;
//定义一个队的相关信息结构体
typedef struct no
{
int val;
string id;
int index;
}no;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,k;
cin>>n>>k;
vector<no> a(n) ;
//用于找到允许参赛的最小名额
int mins=0x3f3f3f3f;
int t;
while(k--)
{
cin>>t;
if(t<mins) mins = t;
}
for(int i=0;i<n;i++)
{
cin>>a[i].val>>a[i].id;
a[i].index=i;
}
auto cmp = [](no& a,no &b){return a.val>b.val;};
//按照实力值进行排序,
sort(a.begin(),a.end(),cmp);
//用于记录一个队当前已经参加的队伍数量
unordered_map<string,int> mp;
//记录最好名次
vector<int> ans(n) ;
//记录当前比赛能达到的最好名词
int rank=0;
//降序保证了排名的准确
for(int i=0;i<a.size();i++)
{
//该校参赛名额未满
if(mp[a[i].id]<mins)
{
mp[a[i].id]++;
rank++;
ans[a[i].index]=rank;
}
//该校参赛名额满了,但为了保证该队能参赛,那么可以理解为它替换了当前参赛的最后一个队
else
{
ans[a[i].index]=rank;
}
}
//输出答案即可
for(int i=0;i<n;i++)
{
cout<<ans[i]<<"\n";
}
}
/*
5 3
1 2 3
100 THU
110 PKU
95 PKU
105 THU
115 PKU
*/