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;
}