http://acm.hdu.edu.cn/showproblem.php?pid=5512
#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
template<class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template<class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int W=13,Z=1e9+7,N=1e5+10;
void fre(){
freopen("in.txt","r",stdin);
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int main(){
// fre();
int caset=0;
scanf("%d",&caset);
char mp[2][20]={"Iaka","Yuwgna"};
for(int i=1;i<=caset;i++){
int n,a,b;
scanf("%d%d%d",&n,&a,&b);
int ans=n/gcd(a,b)-2;
ans%=2;
// printf("%d\n",ans);
printf("Case #%d: %s\n",i,mp[ans]);
}
return 0;
}
能使用的数是两者的gcd
每次取模会使b严格小于被mod的数
#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
typedef long long LL;
template<class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template<class T> inline void gmin(T &a,T b){if(b<a)a=b;}
const int N=1e5+2e6+10,M=3e6+10,Z=1e9+7,W=13;
using namespace std;
int casenum,casei;
int id;
int first[N],w[M],c[M],nxt[M];
LL f[N],F[N];
bool e[N];
struct node{
int x;LL v;
node(){}
node(int x_,LL v_){
x=x_;
v=v_;
}
bool operator <(const node& b)const{return v>b.v;};
};
void ins(int x,int y,int z){
id++;
w[id]=y;
c[id]=z;
nxt[id]=first[x];
first[x]=id;
}
void fre(){
freopen("in.txt","r",stdin);
}
priority_queue<node>q;
void inq(int x,LL dis){
if(dis>=f[x])return;
f[x]=dis;
q.push(node(x,dis));
}
void dijkstra(int st){
MS(f,63);
MS(e,0);
inq(st,0);
// q.push(node(st,0));
while(!q.empty()){
int x=q.top().x;q.pop();
if(e[x])continue;e[x]=1;
for(int z=first[x];z;z=nxt[z])inq(w[z],f[x]+c[z]);
}
}
int main(){
// fre();
scanf("%d",&casenum);
for(casei=1;casei<=casenum;casei++){
MS(first,0);id=1;
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int dis,g,x;
scanf("%d%d",&dis,&g);
int in=n+i;
int out=n+m+i;
ins(in,out,dis);
while(g--){
scanf("%d",&x);
ins(x,in,0);
ins(out,x,0);
}
}
dijkstra(1);
MC(F,f);
dijkstra(n);
LL ans=1e18;
int ed;
for(int i=1;i<=n;i++){
gmax(F[i],f[i]);
if(F[i]<=ans){
ans=F[i];
ed=i;
}
}
if(ans==1e18)printf("Case #%d: Evil John\n",casei);
else{
printf("Case #%d: %lld\n",casei,ans);
for(int i=1;i<ed;i++)if(F[i]==ans)printf("%d ",i);
printf("%d\n",ed);
}
}
return 0;
}
https://blog.csdn.net/snowy_smile/article/details/49535279
折点,两次dijkstra
巧妙剪枝
#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
typedef long long LL;
template<class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template<class T> inline void gmin(T &a,T b){if(b<a)a=b;}
const int N=1e5+2e6+10,M=3e6+10,Z=1e9+7,W=13;
using namespace std;
int casenum,casei;
int n;
char s[505][2020] ;
bool e[505];
int bf(){//this code cannot pass
for(int i=n;i>=1;i--){
for(int j=1;j<i;j++)if(!strstr(s[i],s[j]))return i;
}
return -1;
}
int solve(){
MS(e,1);int ans=-1;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++)if(e[j]){
if(strstr(s[j],s[i]))break;
else{
e[j]=0;gmax(ans,j);
}
}
}
return ans;
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&casenum);
for (casei=1;casei<=casenum;casei++){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",s[i]);
printf("Case #%d: %d\n",casei,solve());
}
return 0;
}
#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
typedef long long LL;
template<class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template<class T> inline void gmin(T &a,T b){if(b<a)a=b;}
const int N=1e5+2e6+10,M=3e6+10,Z=1e9+7,W=13;
using namespace std;
int casenum,casei;
int n;
char s[505][2020] ;
bool e[505];
int nxt[505][505];
int len[505];
void getnxt(int u){
int j=-1;nxt[u][0]=-1;
for(int i=1;i<len[u];i++){
while(j>=0&&s[u][j+1]!=s[u][j])j=nxt[u][j];
//if fail to find, then take previous place's substring' next
if(s[u][j+1]==s[u][i])j++;
nxt[u][i]=j;
}
}
bool kmp(int v,int u){
int j=-1;
for(int i=0;i<len[v];i++){
while(j>=0&&s[u][j+1]!=s[v][i])j=nxt[u][j];
if(s[u][j+1]==s[v][i])j++;
if(j==len[u]-1)return 1;
}
return 0;
}
int solve(){
MS(e,1);int ans=-1;
for(int i=1;i<n;i++){//find string i in string j
for(int j=i+1;j<=n;j++)if(e[j]){
// if(strstr(s[j],s[i]))break;
if(kmp(j,i))break;
else{
e[j]=0;gmax(ans,j);
}
}
}
return ans;
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&casenum);
for (casei=1;casei<=casenum;casei++){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s[i]);
len[i]=strlen(s[i]);
getnxt(i);
}
printf("Case #%d: %d\n",casei,solve());
}
return 0;
}
nxt数组记录了,当前位置结束时,能匹配的最长前缀,0表示1,-1表示0,2表示1以此类推
对于这个问题不如strstr高效
第二个位置表示要找的字符串