【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

你可能感兴趣的:(round)