排位赛补题1

我爆零了,佛了,看来方法不太对T_T;做题太容易先入为主了,一错到底。。。。
1.light oj 1077:How Many Points? (数论gcd)
题意:给定A(x1,y1),B(x2,y2)两个点,求线段AB上有多少个点的x,y坐标都是整数;
思路,一看就知道涉及到AB线段的斜率,不妨设其为k = y/x;且这是将k的最简分数,那么就意味着横坐标每移动x,纵坐标就会移动y,而二者都是整数,那么我们就看能在线段上移动多少次,答案是gcd(x,y)次,由于还要起点也要算,所以+1;不要忘了特判斜率为0或者不存在。

//#include<bits/stdc++.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod (10007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 200+10;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
    int f=1,res=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
    return f*res;
}
ll gcd(ll a,ll b) {
    return (b == 0? a : gcd(b,a%b));
}
int main()
{
    int t,cas = 1;
    cin>>t;
    while(t--) {
        ll x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1 == x2) {
            printf("Case %d: %lld\n",cas++,(max(y1,y2) + 1 - min(y1,y2)));
            continue;
        }else if(y1 == y2) {
            printf("Case %d: %lld\n",cas++,(max(x1,x2) + 1 - min(x1,x2)));
            continue;
        }
        ll disx = abs(x1-x2),disy = abs(y1-y2);
        printf("Case %d: %lld\n",cas++,gcd(disx,disy) + 1);
    }
    return 0;
}

2.鸣人和佐助 (计蒜客,BFS+优先队列)
题意:给一个矩阵和鸣人初始查克拉,鸣人能追上佐助的最短时间,但是有个限制:地图上有些点鸣人要花费查克拉才可以进去,没有查克拉就不能进去;
思路:我当时第一动的就是这个题(太明显了,BFS+优先队列),但是没想清楚,如果单纯地用vis数组给每个点打标记的话,假设一个点到了之后且这种情况下无法追上佐助,那么答案就不存在,因为其他点不能再走这个点;但实际上可能其他点也可能经过这个点并且能追上佐助,举个例子就是:初始查克拉为1

#@*
***
*##
**# 
*#+

直接打标记就结果就是追不上,然而实际上是可以追上的。所以,我们的策略应该是:只要此时走到某个点x的查克拉大于上一次走到这个点的查克拉,那么都有可能达到我们想要的答案;

//#include<bits/stdc++.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod (10007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 1000+10;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
    int f=1,res=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
    return f*res;
}
struct STATUS {
    int x,y,t,ckl;
    bool operator<(const STATUS &a)const {
        return t > a.t;
    }
}s,e;
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
int vis[maxn][maxn],n,m,t;
char mp[maxn][maxn];
bool check(int x,int y) {
    if(x >= 1 && x <= n && y >= 1 && y <= m) return true;
    return false;
}
int bfs() {
    memset(vis,-1,sizeof(vis));
    priority_queue<STATUS>que;
    while(!que.empty()) que.pop();s.t = 0;s.ckl = t;
    que.push(s);vis[s.x][s.y] = t;
    while(!que.empty()) {
        STATUS u = que.top();que.pop();
        if(u.x == e.x && u.y == e.y) return u.t;
        for(int i = 0;i < 4; ++i) {
            int tx = u.x + dx[i],ty = u.y + dy[i];
            if(check(tx,ty) && u.ckl > vis[tx][ty]) { //这个点的查克拉必须要大于即将走到的点的查克拉,不然对于不消耗查克拉的点就会来回跑,不断入队导致mle:
                if(u.ckl == 0 && mp[tx][ty] != '#') {
                    STATUS tmp;tmp.x = tx;tmp.y = ty;tmp.ckl = 0;tmp.t = u.t + 1;
                    if(vis[tx][ty] <= tmp.ckl) {
                        que.push(tmp);vis[tx][ty] = tmp.ckl;
                    }
                }else if(u.ckl) {
                    STATUS tmp;tmp.x = tx;tmp.y = ty;tmp.t = u.t + 1;tmp.ckl = u.ckl;
                    if(mp[tx][ty] == '#') --tmp.ckl;
                    if(vis[tx][ty] <= tmp.ckl) {
                        que.push(tmp);vis[tmp.x][tmp.y] = tmp.ckl;
                    }
                }
            }
        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d%d",&n,&m,&t)) {
        for(int i = 1;i <= n; ++i) {
            for(int j = 1;j <= m;++j){
                cin>>mp[i][j];
                if(mp[i][j] == '@') {
                    s.x = i;s.y = j;
                }
                if(mp[i][j] == '+') {
                    e.x = i;e.y = j;
                }
            }
        }
        printf("%d\n",bfs());
    }
    return 0;
}

3.Censor (scu-4438) (哈希)
题意:删除给定字符串中的敏感串
思路:因为删去后,又可能形成新的敏感串,因此用栈可以快速得到删去一个敏感串后的新串。模拟一个栈,把字符串加进去,如果位于栈顶部的一部分就是敏感串就删去,字符串匹配的话就用哈希就可以。用stl的栈的话,每次删除串就只有循环删除,我写t了,但是模拟的栈就可以O(1)删除;

#include<bits/stdc++.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod (1000000007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 5e6 + 10;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
    int f=1,res=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
    return f*res;
}
string ans;
char str[maxn],word[maxn],stk[maxn];
ll _hash[maxn],f[30],whash;
const ll seed = 233;
int main()
{
    //cout<<f['b']<<endl;
    while(~scanf("%s%s",word,str)) {
        memset(_hash,0,sizeof(_hash));
        whash = 0;
        ll p = 1;
        int wlen = strlen(word),slen = strlen(str);
        for(int i = 0;i < wlen; ++i) {
            whash = (whash * seed % mod + word[i]) % mod;
            p = (p * seed) % mod;
        }
        int top = 0;
        for(int i = 0;i < slen; ++i) {
            stk[++top] = str[i];
            _hash[top] = (_hash[top - 1] * seed % mod + stk[top]) % mod;
            while(top >= wlen) {
                ll cur = (_hash[top] - p * _hash[top - wlen] % mod + mod) % mod;
                if(cur == whash) top -= wlen;
                else break;
            }
        }
        for(int i = 1;i <= top;++i) {
            putchar(stk[i]);
        }
        puts("");
    }
    return 0;
}
发布了33 篇原创文章 · 获赞 14 · 访问量 404

猜你喜欢

转载自blog.csdn.net/qq_44077455/article/details/104055859
今日推荐