2022.3.7

蓝书

AcWing 100. IncDec序列

思路:一开始想的是每个数都减去一个数,以为是平均值,后面想到差分就让每个数减去它前面一个构造了差分数组,因为我们最终是要让序列的每一个数都一样,所以我们让b[1]=a[1],让b[2-n]变成0,预处理出2-n的正数和z和负数和f,一部分的操作次数就是现在z和f消去一部分即min(z,f),剩下一部分我们考虑与a[1]相消去,于是答案为min(z,f)+abs(z-f),这里有abs(z-f)+1种排列方式,+1是因为z和f可能相等,那么a[1]本身就是一种排列方式了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=1e8;
ll a[N],b[N],n;
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n;i++)
        scanf("%lld",&a[i]);
    b[1] = a[1];
    ll z = 0, f = 0,ans=0;
    for (int i = 2; i <= n;i++)
    {
        b[i] = a[i] - a[i - 1];
        if(b[i]>0)
            z += b[i];
        else
            f -= b[i];
    }
    ans += min(z, f)+abs(z-f);
    printf("%lld\n%lld", ans, abs(f - z) + 1);
    return 0;
}

AcWing 101. 最高的牛

思路:如果两头牛要相互看的见的话它们之间的牛的身高必须都小于他们,于是我们对每次输入的牛让它们之间的牛身高都-1,利用差分数组记录一下每对牛之间的相对关系,最后转化成前缀和再加上最高的牛的身高。
一开始判重用的是int数组结果超内存了,改用map就过了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int N=1e4+10,INF=1e8;
map<pair<int, int>,int> mp;
int ans[N];
int main()
{
    int n, p, h, m;
    scanf("%d%d%d%d", &n, &p, &h, &m);
    for (int i = 1; i <= m;i++)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        if(a>b)
            swap(a, b);
        if(mp[{a,b}])
            continue;
        mp[{a,b}] = 1;
        ans[a + 1]--;
        ans[b]++;
    }
    for (int i = 1; i <= n;i++)
    {
        ans[i] +=ans[i-1];
        printf("%d\n", ans[i]+h);
    }
    return 0;
}

AcWing 102. 最佳牛围栏

思路:要求平均值*1000,应该用浮点数二分,为了简便计算,对于每个数我们都先减去二分的平均值,这下问题可以转化成在一个序列中求长度不超过L的非负子段和。因为每块地最多也就只有2000头牛,假设每块地都有2000头牛的话,那么二分答案的最大值也就是2000,因此可以缩小二分的范围,在二分的过程中,我们不必枚举每次的最小值,只需要在i增长的过程中记录下当前的最小值就可以,同时不断更新答案:b[i]-mmin。
一开始减平均值的时候想错了,没在二分的时候减。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=1e8;
int n, m;
double a[N], b[N];
int check(double mid)
{
    double mmin = INF, mmax = -INF;
    for (int i = 1; i <= n;i++)
        b[i] = b[i - 1] + a[i] - mid;
    for (int i = m; i <= n;i++)
    {
        mmin = min(mmin, b[i - m]);
        mmax = max(mmax, b[i] - mmin);
    }
    return mmax >= 0;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n;i++)
    {
        scanf("%lf", &a[i]);
    }
    double l = 0, r = 2000;
    while(r-l>1e-5)
    {
        double mid = (l + r) / 2;
        if(check(mid))
            l = mid;
        else
            r = mid;
    }
    printf("%d", int(r * 1000));
    return 0;
}

AcWing 174. 推箱子

写着写着人突然头晕,晚点补

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N=20+10,INF=1e8;
int n, m, t;
struct node
{
    int x, y, dir;
};
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
PII dist[N][N][4];
node prebox[N][N][4];
int preman[N][N];
bool visman[N][N], visbox[N][N][4];
vector<int> road[N][N][4];
char mp[N][N];
const char op[5] = "nswe";
int check(int x,int y)
{
    if(x>=0&&x<n&&y>=0&&y<m&&mp[x][y]!='#')
        return 1;
    return 0;
}
int bfs2(PII start,PII end,PII box,vector<int>&seq)
{
    memset(visman, 0, sizeof visman);
    memset(preman, -1, sizeof preman);
    visman[start.first][start.second] = 1;
    visman[box.first][box.second] = 1;
    queue<PII> que;
    que.push(start);
    while(que.size())
    {
        auto t = que.front();
        que.pop();
        if(t==end)
        {
            seq.clear();
            while(preman[t.first][t.second]!=-1)
            {
                int dir = preman[t.first][t.second];
                seq.push_back(dir);
                t.first += dx[dir], t.second += dy[dir];
            }
            return seq.size();
        }
        for (int i = 0; i < 4;i++)
        {
            int a = t.first - dx[i], b = t.second - dy[i];
            if(check(a,b)&&!visman[a][b])
            {
                visman[a][b] = 1;
                preman[a][b] = i;
                que.push({a, b});
            }
        }
    }
    return -1;
}
bool bfs1(PII start,PII box,node &ed)
{
    memset(visbox, false, sizeof visbox);
    queue<node> que;
    for (int i = 0; i < 4;i++)
    {
        int bx = box.first - dx[i];
        int by = box.second - dy[i];
        int mx = box.first + dx[i];
        int my = box.second + dy[i];
        if(check(mx,my)&&check(bx,by))
        {
            vector<int> seq;
            int len = bfs2(start, {mx, my}, box, seq);
            if(len==-1)
                continue;
            que.push({bx, by, i});
            visbox[bx][by][i] = 1;
            road[bx][by][i] = seq;
            dist[bx][by][i] = {1, len};
            prebox[bx][by][i] = {box.first, box.second, -1};
        }
    }
    PII mmax = {1e9, 1e9};
    while(que.size())
    {
        auto t = que.front();
        que.pop();
        PII &v = dist[t.x][t.y][t.dir];
        if(mp[t.x][t.y]=='T'&&v<mmax)
        {
            ed = t;
            mmax = v;
        }
        for (int i = 0; i < 4;i++)
        {
            int bx = t.x - dx[i];
            int by = t.y - dy[i];
            int mx = t.x + dx[i];
            int my = t.y + dy[i];
            if(check(mx,my)&&check(bx,by))
            {
                vector<int> seq;
                int len = bfs2({t.x+dx[t.dir],t.y+dy[t.dir]},{mx,my},{t.x,t.y},seq);
                if(len==-1)
                    continue;
                PII distance = {v.first + 1, v.second + len};
                if(!visbox[bx][by][i])
                {
                    que.push({bx, by, i});
                    visbox[bx][by][i] = 1;
                    road[bx][by][i] = seq;
                    dist[bx][by][i] = distance;
                    prebox[bx][by][i] = t;
                }
                else if(dist[bx][by][i]>distance)
                {
                    dist[bx][by][i] = distance;
                    road[bx][by][i] = seq;
                    prebox[bx][by][i] = t;
                }
            }
        }
    }
    //printf("%d\n", mmax.first);
    return mmax.first!=1e9;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)
            break;
        PII start, box; 
        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < m; j ++ )
            {
                cin >> mp[i][j];
                if (mp[i][j] == 'S') start = {i,j};
                else if (mp[i][j] == 'B') box = {i,j};
            }
        node end;
        string ans;
        printf("Maze #%d\n", ++t);
        if(bfs1(start, box, end))
        {
            while (end.dir!=-1)
            {
                ans += op[end.dir] - 32; 
                for (int i = 0; i < road[end.x][end.y][end.dir].size(); i ++ )
                    ans += op[road[end.x][end.y][end.dir][i]]; 
                end = prebox[end.x][end.y][end.dir]; 
            }
            reverse(ans.begin(), ans.end());
            cout << ans << endl<< endl;
        }
        else
        {
            printf("Impossible.\n\n");
        }
    }
    return 0;
}
posted @ 2022-03-07 18:17  menitrust  阅读(29)  评论(0编辑  收藏  举报