A
题目大意
一艘船,有n个人要去对岸,这艘船至少l个,至多r个人操作,每个人有一定耐力,每次划船,船上所有人耐力都会减一
考虑以下模拟,按耐力排序,对耐力处理为(x+1)/2
,即能来回的次数,每次从最后面找l
个人,从最前面找r-l
个人,删除前面的人,后面的人耐力-1,重新排序。复杂度大致为n/l*n*log2(n)
--->n^2
,n取值范围为10^5,明显超出。模拟不行。
只能用数学的方法,由于每次都会有l个人回来,而是否会返回取决于他能否返回,即对耐力的处理为(x-1)/2
,每次运送过去r-l
个,于是,减去最后一次的r个人(不返回),再除以r-l个人,向上取整就是船一共要返回的次数,记为t。
对于耐力超过t的,我们认为多余的部分只能浪费,因为不能拆开来给别人,所有对于每个读入的x,应该要x = min(t,(x-1)/2)
。这就是每个人耐力的最终形式。
于是,使用一个sum(代码里写的是ans,其实意思应该是sum),记下每个人耐力的和,这么做的原因是,当对耐力进行处理之后,每个人的耐力都能拆开为x个1,即你随时都可以去作为返回的人去划船,没有浪费,没有多余,此时除以l(即对于一个分配最完美的队伍,他整体的耐力除以返回需要的耐力和),就是一共能完成几趟的返回次数,跟t比较即可
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n, l, r;
int main()
{
cin >> n >> l >> r;
vector<ll> num(l);
//ll t = ((n-r+(r-l-1))/(r-l));//也ok
ll t = ceil((n-r)*1.0/(r-l));//记得乘1.0!!!
ll x;
ll ans = 0;
for(int i = 0;i<n;i++)
{
cin>>x;
ans+=min(t,(x-1)/2);
}
if(ans/l>=t) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
B
题目大意
有一辆车,能走h
L
题目大意
在一个符合已经完成的9*9数独表中,找到一种地雷分布,使得他符合扫雷的规则,即数字是其周边的地雷数量。
其实也是灵机一动,别看样例,直接在中间找个8,然后其他地方全部是地雷就好,既然麻烦的是怎么把地雷以合适的位置放在数字旁边,不如就把他变成如何把数字放到合适的地雷的中间,那么,放一个数字,且必然存在的数字,就是中间的8了。签到题
代码
写的有点麻烦(
#include<bits/stdc++.h>
using namespace std;
int board[10][10]={0};
int main()
{
int t = 0;
string s;
int i;
int x;
int tx,ty;
for(int i =0;i<9;i++)
{
for(int j = 0;j<9;j++)
{
scanf("%1d",&x);
if(i>0&&i<8 && j>0&&j<8 &&x == 8)
{
tx = i;
ty = j;
}
}
}
int flag = 1;
for(int i = 0;i<9;i++)
{
for(int j = 0;j<9;j++)
{
if(i == tx && j == ty && flag)
{
cout<<'8';
flag = 0;
}
else cout<<'*';
}
cout<<endl;
}
return 0;
}