【TJOI2013 Day1合集】BZOJ3170 松鼠聚会 BZOJ3171 循环格 BZOJ3172 单词

松鼠聚会:

首先题目给出的松鼠之间的距离应该是max(|x1-x2|,|y1-y2|)、、

然后我们知道、如果用x'=x+y,y'=x-y的方式重构所有点的坐标、

两个点之间的距离就变成了max(|x1'-x2'|,|y1'-y2'|)、、

于是我们用给的两个数字解一个一元二次方程得到原来的坐标、、

然后前缀和乱搞搞统计曼哈顿距离和就好了、

 

Code:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <queue>
 
#define ps system("pause")
#define message printf("*\n")
#define pb push_back
#define X first
#define Y second
#define PII pair<int,int>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
 
typedef long long ll;
 
using namespace std;
 
struct node{
    double x,y;
    int id;
}p[100010];
 
bool cmp1(node a,node b){
    return  a.x<b.x;
}
 
bool cmp2(node a,node b){
    return  a.y<b.y;
}
 
double sx=0,sy=0,ts;
double ans[100010];
int n;
 
int main(){
    scanf("%d",&n);
    rep(i,1,n){
        double xx,yy;
        scanf("%lf%lf",&xx,&yy);
        p[i].x=(xx+yy)/2;p[i].y=(xx-yy)/2;
        sx+=p[i].x;sy+=p[i].y;p[i].id=i;
    }
    sort(p+1,p+n+1,cmp1);ts=0;
    rep(i,1,n){
        ans[p[i].id]+=(i-1)*p[i].x-ts;
        ans[p[i].id]+=(sx-ts)-(n-i+1)*p[i].x;
        ts+=p[i].x;
    }
    sort(p+1,p+n+1,cmp2);ts=0;
    rep(i,1,n){
        ans[p[i].id]+=(i-1)*p[i].y-ts;
        ans[p[i].id]+=(sy-ts)-(n-i+1)*p[i].y;
        ts+=p[i].y;
    }
    double s=1e18;
    rep(i,1,n)  s=min(s,ans[i]);
    printf("%.0lf\n",s);
    return  0;
}

  

循环格:

或许可以生成所有合法状态之后按行或者列方向做状压DP、、

但是我太弱了于是写了费用流、

图形成完美循环的充要条件是每个点的入度和出度都是1、、

于是拆点为入和出、由S向入i,T向出i分别连容量为1费用为0的边、、

对每个点入i,向相邻点的出j连容量为1的边、、

然后在最后的最大流中入i到出j如果存在流量就代表i上字母是指向j的、、

所以对原有的字母指向的边费用为0,因为不用修改、其它的就是1了、、

最后跑mincost-maxflow就好了、、

 

Code:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <queue>
 
#define ps system("pause")
#define message printf("*\n")
#define pb push_back
#define X first
#define Y second
#define PII pair<int,int>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
 
typedef long long ll;
 
using namespace std;
 
#define inf 9999999
 
int l,r=2,n,m,S,T;
char c[20][20];
int t[100010],w[100010],v[100010],next[100010],s[100010];
int g[2010],e[2010],d[2010],fr[2010],uc[2010],ans=0;
bool ud[2010];
bool vis[1010];
int in[20][20],ou[20][20];
 
void addedge(int aa,int bb,int cc,int vv){
    //printf("%d %d %d %d\n",aa,bb,cc,vv);
    t[r]=bb;w[r]=cc;v[r]=vv;
    if  (!ud[aa])   g[aa]=e[aa]=r,ud[aa]=true;
    else    next[e[aa]]=r,e[aa]=r;
    r++;
    t[r]=aa;w[r]=0;v[r]=-vv;
    if  (!ud[bb])   g[bb]=e[bb]=r,ud[bb]=true;
    else    next[e[bb]]=r,e[bb]=r;
    r++;
}
  
bool spfa(){
    l=1;r=1;s[1]=S;
    memset(vis,0,sizeof vis);
    memset(fr,0,sizeof fr);
    memset(uc,0,sizeof uc);
    rep(i,S,T)    d[i]=inf;
    d[S]=0;vis[S]=true;
    while   (l<=r){
        for (int u=g[s[l]];u;u=next[u])
            if  (w[u] && d[t[u]]>d[s[l]]+v[u]){
                d[t[u]]=d[s[l]]+v[u];
                fr[t[u]]=s[l];uc[t[u]]=u;
                if  (!vis[t[u]]){
                    s[++r]=t[u];
                    vis[t[u]]=true;
                }
            }
        vis[s[l]]=false;
        l++;
    }
    return  d[T]!=inf;
}
  
int argu(){
    int cur=T,res=inf,flow=0;
    while   (cur!=S){
        res=min(res,w[uc[cur]]);
        flow+=v[uc[cur]];
        cur=fr[cur];
    }
    cur=T;
    while   (cur!=S){
        w[uc[cur]]-=res;
        w[uc[cur]^1]+=res;
        cur=fr[cur];
    }
    return  res*flow;
}
 
int main(){
    scanf("%d%d\n",&n,&m);
    rep(i,1,n){
        scanf(" ");
        rep(j,1,m)  c[i][j]=getchar();
    }
     
    rep(i,1,n)  rep(j,1,m){
        in[i][j]=(i-1)*m+j;
        ou[i][j]=in[i][j]+n*m;
    }
     
    S=0,T=n*m*2+1;
    rep(i,1,n)  rep(j,1,m){
        addedge(S,in[i][j],1,0);
        addedge(ou[i][j],T,1,0);
        switch  (c[i][j]){
            case    'L':
                addedge(in[i][j],ou[i][(j-1-m)%m+m],1,0);
                addedge(in[i][j],ou[i][j%m+1],1,1);
                addedge(in[i][j],ou[(i-1-n)%n+n][j],1,1);
                addedge(in[i][j],ou[i%n+1][j],1,1);
                break;
            case    'R':
                addedge(in[i][j],ou[i][(j-1-m)%m+m],1,1);
                addedge(in[i][j],ou[i][j%m+1],1,0);
                addedge(in[i][j],ou[(i-1-n)%n+n][j],1,1);
                addedge(in[i][j],ou[i%n+1][j],1,1);
                break;
            case    'U':
                addedge(in[i][j],ou[i][(j-1-m)%m+m],1,1);
                addedge(in[i][j],ou[i][j%m+1],1,1);
                addedge(in[i][j],ou[(i-1-n)%n+n][j],1,0);
                addedge(in[i][j],ou[i%n+1][j],1,1);
                break;
            case    'D':
                addedge(in[i][j],ou[i][(j-1-m)%m+m],1,1);
                addedge(in[i][j],ou[i][j%m+1],1,1);
                addedge(in[i][j],ou[(i-1-n)%n+n][j],1,1);
                addedge(in[i][j],ou[i%n+1][j],1,0);
                break;
        }
    }
    while   (spfa())    ans+=argu();
    printf("%d\n",ans);
    return  0;
}

  

单词:

这题有一万种方法可以做、、弱*的LZ就用KMP水过了、、

大致还可以用SA、AC自动机、字符串HASH之类的过吧、、

 

Code:

var
  n,i,j,cur,k,p,ans:longint;
  s:array [0..2000010] of char;
  ff:array [0..2000010] of longint;
  st,len:array [0..201] of longint;
  w:array [0..201,0..100010] of char;
begin
  readln(n);
  cur:=0;
  for i:=1 to n do
    begin
      st[i]:=cur+1;p:=0;
      while not eoln do
        begin
          inc(cur);
          read(s[cur]);
          inc(p);
          w[i][p]:=s[cur];
        end;
      len[i]:=p;
      inc(cur);s[cur]:='#';
      readln;
    end;
  for i:=1 to n do
    begin
      ff[1]:=0;k:=0;
      for j:=2 to len[i] do
        begin
          while (k>0) and (w[i][k+1]<>w[i][j]) do k:=ff[k];
          if w[i][k+1]=w[i][j] then inc(k);
          ff[j]:=k;
        end;
      k:=0;ans:=0;
      for j:=1 to cur do
        begin
          while (k>0) and (w[i][k+1]<>s[j]) do k:=ff[k];
          if w[i][k+1]=s[j] then inc(k);
          if k=len[i] then
            begin
              inc(ans);
              k:=ff[k];
            end;
        end;
      writeln(ans);
    end;
end.

  

posted @ 2013-05-21 17:50  JS_Shining  阅读(1285)  评论(0编辑  收藏  举报