我爆零了,佛了,看来方法不太对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;
}