AcWing 双指针、BFS与图论打卡

1238. 日志统计

https://www.acwing.com/problem/content/1240/
使用双指针算法维护一个动态区间

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int>PII;//使用pair 默认按第一个大小然后第二个大小排序
const int N=1e5+5;
PII a[N];
int n,d,k;
int cnt[N];
bool st[N];
int main(){
    cin>>n>>d>>k;
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    sort(a,a+n);
    for(int i=0,j=0;i<n;i++){
        int id=a[i].y;
        cnt[id]++;
        while(a[i].x-a[j].x>=d){
            cnt[a[j].y]--;
            j++;
        }
        if(cnt[id]>=k) st[id]=true;
    }
    for(int i=0;i<=100000;i++){
        if(st[i]) cout<<i<<endl;
    }
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1101. 献给阿尔吉侬的花束

https://www.acwing.com/problem/content/1103/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
int T;
int R,C;
const int INF=0x3f3f3f3f;
char a[250][205];
int dist[250][250];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
typedef pair<int,int>PII;
int bfs(int x,int y){
    memset(dist,0x3f,sizeof dist);
    dist[x][y]=0;
    queue<PII> q;
    q.push({x,y});
    while(q.size()){
        auto t=q.front();
        q.pop();
        int x=t.x,y=t.y;
        if(a[x][y]=='E'){
            return dist[x][y];
        }
        for(int i=0;i<4;i++){
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(dist[nx][ny]==INF && nx>=1 && nx<=R && ny >=1 && ny<=C && a[nx][ny]!='#'){
                dist[nx][ny]=dist[x][y]+1;
                q.push({nx,ny});
            }
        }
    }
    return -1;
}
int main(){
    cin>>T;
    while(T--){
        cin>>R>>C;
        int x,y;
        for(int i=1;i<=R;i++){
            for(int j=1;j<=C;j++){
                cin>>a[i][j];
                if(a[i][j]=='S'){
                    x=i;
                    y=j;
                }
            }
        }
        int temp=bfs(x,y);
        if(temp==-1) puts("oop!");
        else cout<<temp<<endl;
    }
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1113. 红与黑

https://www.acwing.com/problem/content/1115/

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 25;

int n, m;
char g[N][N];
bool st[N][N];

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int dfs(int x, int y)
{
    int cnt = 1;

    st[x][y] = true;
    for (int i = 0; i < 4; i ++ )
    {
        int a = x + dx[i], b = y + dy[i];
        if (a < 0 || a >= n || b < 0 || b >= m) continue;
        if (g[a][b] != '.') continue;
        if (st[a][b]) continue;

        cnt += dfs(a, b);
    }

    return cnt;
}

int main()
{
    while (cin >> m >> n, n || m)
    {
        for (int i = 0; i < n; i ++ ) cin >> g[i];

        int x, y;
        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < m; j ++ )
                if (g[i][j] == '@')
                {
                    x = i;
                    y = j;
                }

        memset(st, 0, sizeof st);
        cout << dfs(x, y) << endl;
    }

    return 0;
}

1224. 交换瓶子

https://www.acwing.com/problem/content/description/1226/

#include<iostream>
using namespace std;

const int N=10010;
int s[N];
int n,cnt;

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&s[i]);
    for(int i=1;i<=n;i++)
        while(s[i]!=i) swap(s[i], s[s[i]]), cnt++;

    cout<<cnt;
    return 0;
}

1240. 完全二叉树的权值

https://www.acwing.com/problem/content/1242/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=2e5+5;
int n;
int a[N];
int fun(int x){
    if(x==0) return 1;
    else return 1<<x;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",a+i);
    }
    int start=1;
    int cnt=0;
    LL maxv=0,maxindex=0;
    while(n>0){
        LL temp=0;
        int k=fun(cnt);
        n-=k;
        while(k--){
            temp+=a[start];
            start++;
        }
        if(temp>maxv){
            maxv=temp;
            maxindex=cnt;
        }
        cnt++;
    }
    cout<<maxindex+1<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1096. 地牢大师

https://www.acwing.com/problem/content/1098/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;

struct Point
{
    int x, y, z;
};

int L, R, C;
char g[N][N][N];
Point q[N * N * N];
int dist[N][N][N];

int dx[6] = {1, -1, 0, 0, 0, 0};
int dy[6] = {0, 0, 1, -1, 0, 0};
int dz[6] = {0, 0, 0, 0, 1, -1};

int bfs(Point start, Point end)
{
    int hh = 0, tt = 0;
    q[0] = start;
    memset(dist, -1, sizeof dist);
    dist[start.x][start.y][start.z] = 0;

    while (hh <= tt)
    {
        auto t = q[hh ++ ];

        for (int i = 0; i < 6; i ++ )
        {
            int x = t.x + dx[i], y = t.y + dy[i], z = t.z + dz[i];
            if (x < 0 || x >= L || y < 0 || y >= R || z < 0 || z >= C) continue;  // 出界
            if (g[x][y][z] == '#') continue;  // 有障碍物
            if (dist[x][y][z] != -1) continue;  // 之前走到过

            dist[x][y][z] = dist[t.x][t.y][t.z] + 1;
            if (x == end.x && y == end.y && z == end.z) return dist[x][y][z];

            q[ ++ tt] = {x, y, z};
        }
    }

    return -1;
}

int main()
{
    while (scanf("%d%d%d", &L, &R, &C), L || R || C)
    {
        Point start, end;
        for (int i = 0; i < L; i ++ )
            for (int j = 0; j < R; j ++ )
            {
                scanf("%s", g[i][j]);
                for (int k = 0; k < C; k ++ )
                {
                    char c = g[i][j][k];
                    if (c == 'S') start = {i, j, k};
                    else if (c == 'E') end = {i, j, k};
                }
            }

        int distance = bfs(start, end);
        if (distance == -1) puts("Trapped!");
        else printf("Escaped in %d minute(s).\n", distance);
    }

    return 0;
}

1233. 全球变暖

https://www.acwing.com/problem/content/1235/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;

int n;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

void bfs(int sx, int sy, int &total, int &bound)
{
    int hh = 0, tt = 0;
    q[0] = {sx, sy};
    st[sx][sy] = true;

    while (hh <= tt)
    {
        PII t = q[hh ++ ];

        total ++ ;
        bool is_bound = false;
        for (int i = 0; i < 4; i ++ )
        {
            int x = t.x + dx[i], y = t.y + dy[i];
            if (x < 0 || x >= n || y < 0 || y >= n) continue;  // 出界
            if (st[x][y]) continue;
            if (g[x][y] == '.')
            {
                is_bound = true;
                continue;
            }

            q[ ++ tt] = {x, y};
            st[x][y] = true;
        }

        if (is_bound) bound ++ ;
    }
}

int main()
{
    scanf("%d", &n);

    for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);

    int cnt = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            if (!st[i][j] && g[i][j] == '#')
            {
                int total = 0, bound = 0;
                bfs(i, j, total, bound);
                if (total == bound) cnt ++ ;
            }

    printf("%d\n", cnt);

    return 0;
}

1207. 大臣的旅费

https://www.acwing.com/problem/content/1209/
本质求树的直径
树的直径求法:
任意取一个x,找到离它最远的点y 然后找离点y最远的距离就是树的直径

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=100010,M=2*N;
int h[N],e[M],ne[M],w[M],idx;
int dist[N];
int n;
void add(int a,int b,int c){
    e[idx]=b;
    w[idx]=c;
    ne[idx]=h[a];
    h[a]=idx++;
}
void dfs(int u,int father,int distance){
    dist[u]=distance;
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j!=father){//不能回到之前递归过的地方
            dfs(j,u,distance+w[i]);
        }
    }
}
int main(){
    memset(h,-1,sizeof h);
    cin>>n;
    for(int i=0;i<n-1;i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    dfs(1,-1,0);
    int u=1;
    for(int i=1;i<=n;i++){
        if(dist[i]>dist[u]) u=i;
    }
    dfs(u,-1,0);
    for(int i=1;i<=n;i++){
        if(dist[i]>dist[u]) u=i;
    }
    int s=dist[u];
     printf("%lld\n", s * 10 + s * (s + 1ll) / 2);
  return 0;
}
//  freopen("testdata.in", "r", stdin);
posted @ 2021-05-18 12:17  一个经常掉线的人  阅读(50)  评论(0)    收藏  举报