https://atcoder.jp/contests/abc208/tasks/abc208_a
A - Rolling Dice
题意:给你两个数 a , b。问你能不能用从1、2、3、4、5、6中拿a次,其之和为b。
比如:给你a=2,b=5,你可以拿2、3;给你a=2;b=13则无法完成操作;给你a=100,给你b=99同样不能完成操作。
思路O(1):思维题。无论给你的是什么,只要我拿a次6 都 ≥b 且拿 a次1 都 ≤b 则说明我一定能拿a次,其之和为b。
代码:
#include<bits/stdc++.h>
#define ll long long
#define hh 0x3f3f3f3f
const int maxn=1e5+5;
using namespace std;
void solve()
{
int a,b;
cin>>a>>b;
if(a*6>=b&&a*1<=b)cout<<"Yes";
else cout<<"No";
}
int main()
{
ios::sync_with_stdio(0);cout.tie(0);cin.tie(0);
solve();
return 0;
}
https://atcoder.jp/contests/abc208/tasks/abc208_b
B - Factorial Yen Coin
题意:现在只10种面额的钱,他们分别是1!、2!、3!、4!、5!...10!。这里的N!=n*(n-1)*(n-2)....*2*1;每种面额你都有100张,在没有找零的情况下,问你最少要用多少张面额的钱来买p元的物品。(通过证明,这个答案是存在的、唯一的)
思路:肯定是从面额高的往面额低的钱开始找,我们用f[i]表示第i个面额的钱,其中 f[i] = i! 。如果
f[i] <= p ,那么我们就算 f[i] 最多能拿temp张,那么我们就让p-=temp* f [i],知道循环到p=0退出。
代码:
#include<bits/stdc++.h>
#define ll long long
#define hh 0x3f3f3f3f
const int maxn=1e5+5;
using namespace std;
ll f[15];
void solve()
{
int p,cnt=0,tail=10;
cin>>p;
while(1)
{
while(f[tail]>p)//找到f[tail]<=p
{
tail--;
}
int temp=p/f[tail];//看看最多能用多少张 f[tail]
// if(temp>100)
// {
// cnt+=100;
// p-=100*f[tail];
// tail--;
// continue;
// }
cnt+=temp;//计数
p-=f[tail]*temp;//更新p
if(p==0)break;//知道p=0退出循环
}
cout<<cnt<<endl;
}
int main()
{
ios::sync_with_stdio(0);cout.tie(0);cin.tie(0);
for(int i=1;i<=10;i++)
{
ll temp=1;
for(int j=i;j>=1;j--)
{
temp*=j;
}
f[i]=temp;
}
solve();
return 0;
}
https://atcoder.jp/contests/abc208/tasks/abc208_c
C - Fair Candy Distribution
题意:给你n个城市,每个城市都有自己的ID (ai),城市与城市是不同的;再给你k课糖果,让你通过以下两个操作,直到你手中的糖果被分完为止。
操作1:如果你手中的糖果数量k >城市的数量 n,则让你给每个城市一颗糖果。
操作2:如果 k < n ,则从ID小的城市开始分,即ai小的开始分,每个城市一颗糖,直到分到第k小的城市为止,游戏结束。
代码:
#include<bits/stdc++.h>
#define ll long long
#define hh 0x3f3f3f3f
const int maxn=2e5+5;
using namespace std;
struct node
{
ll id,v,ans;
}a[maxn];
bool cmp1(node x,node y){return x.v<y.v;}
bool cmp2(node x,node y){return x.id<y.id;}
void solve()
{
ll n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i].v;
a[i].id=i,a[i].ans=0;
}
sort(a+1,a+1+n,cmp1);
if(k>=n)
{
ll tp=k/n;//当 k>n 时计算每个城市能得到多少颗糖果
k-=tp*n; //更新 k
for(int i=1;i<=k;i++)//这是k<n的情况,从id小的开始分直到分到第k小的id,游戏结束
{
a[i].ans++;
}
sort(a+1,a+1+n,cmp2);
for(int i=1;i<=n;i++)
{
cout<<a[i].ans+tp<<endl;
}
}
else//k<n的情况
{
for(int i=1;i<=k;i++)a[i].ans++;
sort(a+1,a+1+n,cmp2);
for(int i=1;i<=n;i++)cout<<a[i].ans<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);cout.tie(0);cin.tie(0);
solve();
return 0;
}
https://atcoder.jp/contests/abc208/tasks/abc208_d
D - Shortest Path Queries 2
这个题目要求很乱,英文也不好理解。
大体意思就是给定一个N个顶点,M条边的一个有权无向图,然后定义了一个函数,这个函数表示从s节点到t节点走k步的最短距离,同时如果s==t,那么距离就是0.
然后求所有的s、t、k的和。
其实就是用Floyed算法求出每个顶点到其他顶点的最短路径然后求和,但是注意的是这个k因为从1开始,所以有的顶点是无法到达的,此时设置为无穷大,具体在循环中只需要判断是不是无穷大,不是才将距离加入到结果中。
代码:
#include<bits/stdc++.h>
#define ll long long
#define hh 0x3f3f3f3f
const int maxn=2e5+5;
using namespace std;
ll f[405][405],n,m,sum;
void Floyed()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(f[i][j]!=hh)sum+=f[i][j];
}
}
}
}
int main()
{
ios::sync_with_stdio(0);cout.tie(0);cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)continue;
f[i][j]=hh;
}
}
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
f[a][b]=c;
}
Floyed();
cout<<sum;
return 0;
}