暑假ts06

B题:http://poj.org/problem?id=1852

蚂蚁题:其实每个蚂蚁如果相撞,返回,也就是帮别人走了一段路;

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
int main(){
	int _;
	scanf("%d",&_);
	while(_--){
		int l,n;
		scanf("%d%d",&l,&n);
		int maxx=-inf,minn=-inf;
		for(int i=1;i<=n;i++){
			int locted,res,cnt;
			scanf("%d",&locted);
			//res=(l-locted);
			res=min(locted,l-locted);
			cnt=max(locted,l-locted);
			minn=max(minn,res);
			
			maxx=max(maxx,cnt);
		}
		printf("%d %d\n",minn,maxx);
	}
	return 0;
}

H题:求前缀和后缀相同,其实就是KMP,KMP记录的就是 s[K]  = =s [J-K]——S[J-1]处相同http://poj.org/problem?id=2752

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
using namespace std;
const int N = 4e5+10;
string s,t;
int Next[N];
int a[N];
void getn(){
    int len=s.size();
    int j=0,k=-1;
    Next[j]=k;
    while(j<len){
        if(k==-1||s[j]==s[k]){
            j++;k++;
            Next[j]=k;
        }
        else
            k=Next[k];
    }
}
int main()
{
    while(cin>>s){
        getn();
        int le=s.size();
        int j=Next[le];
        int cnt=0;
        while(j>0){
            a[cnt++]=j;
            j=Next[j];
        }
        for(int i=cnt-1;i>=0;i--){
            printf("%d ",a[i]);
        }
        printf("%d\n",le);
    }
    return 0;
}

I题:KMP匹配;http://poj.org/problem?id=3461

#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
char w[10010],t[1000100];
int nex[10010];
void getn(){
    int len=strlen(w);
    int j=0,k=-1;
    nex[j]=k;
    while(j<len){
        if(k==-1||w[j]==w[k])
            nex[++j]=++k;
        else
            k=nex[k];
    }
}
int main()
{
    int _;
    cin>>_;
    while(_--){
        cin>>w>>t;
        getn();

        int ans=0;
        int len1=strlen(t),len2=strlen(w);
        //for(int i=0;i<len2;i++)cout<<nex[i]<<' ';
        int j=-1,i=-1;
        while(i<len1){
            if(j==-1||w[j]==t[i]){
                j++,i++;
                if(j==len2){
                    ans++;
                    j=nex[j];
                }
            }
            else
                j=nex[j];
        }
        cout <<ans << endl;
    }

    return 0;
}

J最短路径模板:http://poj.org/problem?id=2387

dijkstra算法;

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 1005;
int graph[N][N];
int dis[N];
int vis[N];
int t,n;
void init(){
    for(int i=0;i<=n;i++){
        dis[i]=inf;
        vis[i]=0;
        for(int j=0;j<=n;j++){
            if(i==j)graph[i][j]=0;
            else
            graph[i][j]=inf;
        }
    }
}

void disj(){
    for(int i=1;i<=n;i++){
        dis[i]=graph[1][i];
    }
    vis[1]=1;
    for(int v=1;v<n;v++){
        int flag=0,m=inf;

        for(int i=1;i<=n;i++){
            if(!vis[i]&&dis[i]<m){
                m=dis[i];
                flag=i;
            }
        }
        //cout<<flag<<endl;
        vis[flag]=1;
        for(int i=1;i<=n;i++){
            if(!vis[i]&&dis[i]>dis[flag]+graph[flag][i])
                dis[i]=dis[flag]+graph[flag][i];
        }
    }
}
int main()
{

    scanf("%d%d",&t,&n);
    init();
    for(int i=1;i<=t;i++){
        int u,v,c;
        scanf("%d%d%d",&u,&v,&c);
        if(graph[u][v]>c){
            graph[u][v]=c;
            graph[v][u]=c;
        }
    }
    disj();

    cout << dis[n] << endl;
    return 0;
}

用优先队列优化的dijkstra,即省去,第一个for循环寻找已加入集合中最短的边;

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 1005;
struct Edge{
    int to;
    int cost;
};
vector<Edge>edge[N];
int dis[N];
int vis[N];
int t,n;
typedef pair<int,int> P;
void disj(){
    fill(dis,dis+n+1,inf);
    fill(vis,vis+n+1,0);
    priority_queue<P,vector<P>,greater<P> > que;
    dis[1]=0;
    que.push(P(0,1));
    while(!que.empty()){
        P p=que.top();
        que.pop();
        int v=p.second;
        if(vis[v])continue;
        vis[v]=1;
        for(int i=0;i<edge[v].size();i++){
            Edge e=edge[v][i];
            if(dis[e.to]>dis[v]+e.cost){
                dis[e.to]=dis[v]+e.cost;
                que.push(P(dis[e.to],e.to));
            }

        }
    }
}
int main()
{
    scanf("%d%d",&t,&n);
    //init();
    for(int i=1;i<=t;i++){
        int u,v,c;
        scanf("%d%d%d",&u,&v,&c);
        Edge f;
        f.to=v,f.cost=c;
        edge[u].push_back(f);
        f.to=u,f.cost=c;
        edge[v].push_back(f);
    }
    disj();
    cout << dis[n] << endl;
    return 0;
}

夫洛里得,超时

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 1005;
int graph[N][N];
int t,n;
void init(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            graph[i][j]=inf;
    }
}
void fro(){

    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(graph[i][j]>graph[i][k]+graph[k][j])
                    graph[i][j]=graph[i][k]+graph[k][j];
            }
        }
    }
}
int main()
{

    scanf("%d%d",&t,&n);
    init();
    for(int i=1;i<=t;i++){
        int u,v,c;
        scanf("%d%d%d",&u,&v,&c);
        if(graph[u][v]>c){
            graph[u][v]=c;
            graph[v][u]=c;
        }
    }
    fro();

    cout << graph[1][n] << endl;
    return 0;
}

bellman-ford,不断松弛所有边;

#include<iostream>
#include<cstdlib>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 2005;
int u[N*2];
int v[N*2];
int w[N*2];
int dis[1005];
int main(){
    int t,n;
    cin>>t>>n;
    for(int i=1;i<=t*2;i+=2){
        cin>>u[i]>>v[i]>>w[i];
        u[i+1]=v[i],v[i+1]=u[i],w[i+1]=w[i];
    }
    for(int i = 1; i <= n; i ++)dis[i]=inf;
    dis[1]=0;
    bool flag;
    for(int k=1;k<n;k++){
        flag=false;
        for(int i=1;i<=t*2;i++){
            if(dis[u[i]]+w[i]<dis[v[i]]){
                dis[v[i]]=dis[u[i]]+w[i];
                flag=true;
            }
        }
        if(!flag)break;
    }
    cout<<dis[n]<<endl;
    return 0;
}

SPAF,利用优先队列,使其不必要的边,不加松弛;

#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 1005;
int t,n;
struct node{
    int to;
    int cost;
};
int dis[N];
vector<node> ve[1005];

void spfa(){
    fill(dis,dis+n+1,inf);
   // priority_queue<node,vector<node>,greater<node> > q;
   queue<int>q;
   dis[1]=0;
   q.push(1);
   int now;
   while(!q.empty()){
      now=q.front();
      q.pop();
      for(int i=0;i<ve[now].size();i++){
        node e=ve[now][i];
        if(dis[e.to]>dis[now]+e.cost){
            dis[e.to]=dis[now]+e.cost;
            q.push(e.to);
        }
      }
   }
}
int main(){
    cin>>t>>n;
    for(int i=1;i<=t;i++){
        int u,v,w;
        cin>>u>>v>>w;
        node k;
        k.to=v,k.cost=w;
        ve[u].push_back(k);
        k.to=u,k.cost=w;
        ve[v].push_back(k);
    }
    spfa();
    cout<<dis[n]<<endl;
    return 0;
}

K题:二分http://poj.org/problem?id=3104

#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long int ll;
const int N = 1e6+10;
ll a[N];
int n,k;
bool check(ll res){
    ll cnt=0;
    for(int i=1;i<=n;i++){
        if(a[i]>res)
        //cnt+=ceil((a[i]-res)*1.0/(k-1));
        cnt+=(a[i]-res+k-2)/(k-1); //分子+上 分母-1   等于向上取整 
    }
    if(cnt<=res)return true;
    return false;
}
int main()
{
    ll ma=-999;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        ma=max(ma,a[i]);
    }

    cin>>k;
    if(k==1){
        printf("%lld\n",ma);

    }
    else{
        ll l=1,r=ma,ans;
        while(l<=r) {
            ll mid=(l+r)/2;
            if(check(mid)) {
                ans=mid;
                r=mid-1;
            } else
                l=mid+1;
        }
        printf("%lld\n",ans);
    }

    return 0;
}
发布了97 篇原创文章 · 获赞 3 · 访问量 9438

猜你喜欢

转载自blog.csdn.net/foolishpichao/article/details/99566598
ts
06