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;
}