【TCO2013 Round1A】Solutions

  230来分就晋级了,偏偏我出了点事故第一题低分,第二题被cha,第三题没时间写。。。准备滚回去R1B了。。。

 

【250】

  大意是一个n×m的矩阵,每次可以将一个格子中的数±1,问最少操作次数使得最大值与最小值相差不超过1。格子中的数值为0~9。

  枚举最小值min,最大值max=min+1,然后挨着判断一下。

View Code
 1 class HouseBuilding {
 2 public:
 3     int getMinimum(vector <string>);
 4 };
 5 
 6 int HouseBuilding::getMinimum(vector <string> area) {
 7     int n=area.size();
 8     int len=area[0].length();
 9     int ans=inf;
10     for(int low=0;low<9;low++){
11             int tmp=0;
12             for(int i=0;i<n;i++)
13                 for(int j=0;j<len;j++){
14                     int cur=area[i][j]-'0';
15                     if(cur>low+1) tmp+=(cur-low-1);
16                     else if(cur<low) tmp+=(low-cur);
17                 }
18             gmin(ans,tmp);
19         }
20     return ans;
21 }

 

【500】

  给定若干区间,求最小的公差d使得等差数列{0,d,2d...nd},nd>D,且an不在区间内(不包括边界)。

  感觉这题比较难,因为区间坐标都是整数,所以d≥1,对于每个区间的右端点R[i],枚举k使得kd≥R[i],然后判断是否(k-1)d≤L[i].判断方法当时没想粗,然后乱写了一个,果断被cha。。。

View Code
 1 class TheFrog {
 2 public:
 3     double getMinimum(int, vector <int>, vector <int>);
 4 };
 5 
 6 double TheFrog::getMinimum(int D, vector <int> L, vector <int> R) {
 7     int n=L.size();
 8     double ans=1e100;
 9     for(int i=0;i<n;i++){
10         for(int step=1;step<=R[i];step++){
11             bool check=true;
12             double len=R[i]*1.0/step;
13             if(len>=(double)D) gmin(ans,(double)D);
14             for(int j=0;j<n;j++){
15                 if(floor(L[j]*1.0/len+eps)*len+len+eps<R[j]){
16                     check=false;
17                     break;
18                 }
19             }
20             if(check) gmin(ans,R[i]*1.0/step);
21         }
22     }
23     return ans;
24 }

 

【1000】

  打开这题的时候已经没时间了。。。

  要求改变最少的箭头使得任意一个点都在环内。

  任意一个点属于一个环 ↔每个点出度入度都是1

  拆点,连边时与原箭头方向相同费用为0,不同费用为1。最大流即保证出入度为1,即任意一个点属于一个环。跑最小费用流。

View Code
 1 struct EDGE{
 2         int pnt,cap,cost;
 3         EDGE *pre,*ref;
 4         EDGE(){}
 5         EDGE(int _pnt,int _cap,int _cost,EDGE *_pre):pnt(_pnt),cap(_cap),cost(_cost),pre(_pre){}
 6     }Edge[mm],*SP=Edge,*edge[mn],*path[mn];
 7 
 8     queue<int> q;
 9     int dist[mn],mincost,source,sink;
10     bool vis[mn];
11     char dir[4]={'D','U','L','R'};
12 
13 class DirectionBoard {
14 public:
15     int getMinimum(vector <string>);
16 };
17 
18 void addedge(int a,int b,int c){
19     edge[a]=new(++SP)EDGE(b,1,c,edge[a]);
20     edge[b]=new(++SP)EDGE(a,0,-c,edge[b]);
21     edge[a]->ref=edge[b],edge[b]->ref=edge[a];
22 }
23 
24 bool SPFA(){
25     memset(dist,0x7f,sizeof(dist));
26     dist[source]=0;
27     q.push(source);
28     while(!q.empty()){
29         int i=q.front();q.pop();
30         vis[i]=false;
31         for(EDGE *j=edge[i];j;j=j->pre)
32             if(j->cap>0 && dist[j->pnt]>dist[i]+j->cost){
33                 dist[j->pnt]=dist[i]+j->cost;
34                 path[j->pnt]=j;
35                 if(!vis[j->pnt]){
36                     q.push(j->pnt);
37                     vis[j->pnt]=true;
38                 }
39             }
40     }
41     return dist[sink]<10000;
42 }
43 
44 void augment(){
45     mincost+=dist[sink];
46     for(int i=sink;i!=source;i=path[i]->ref->pnt)
47         path[i]->cap--,path[i]->ref->cap++;
48 }
49 
50 void costflow(){
51     while(SPFA()) augment();
52 }
53 
54 int DirectionBoard::getMinimum(vector <string> board) {
55     int n=board.size();
56     int m=board[0].length();
57     int size=n*m;
58     source=size*2,sink=source+1;
59     for(int i=0;i<n;i++)
60         for(int j=0;j<m;j++){
61             addedge(source,i*m+j,0);
62             addedge(i*m+j+size,sink,0);
63             for(int k=0;k<4;k++){
64                 int x=(i+dx[k]+n)%n,y=(j+dy[k]+m)%m;
65                 addedge(i*m+j,x*m+y+size,dir[k]!=board[i][j]);
66             }
67         }
68     costflow();
69     return mincost;
70 }

 

  唉。。。。。真可惜。。。。。

  转载注明出处:http://www.cnblogs.com/Delostik/archive/2013/02/24/2924316.html

posted @ 2013-02-24 16:57  Delostik  阅读(316)  评论(0编辑  收藏  举报