做過TC的比賽感覺上了相對來說,CodeForces的比賽應該會簡單一些,不過很可惜,那晚第三題並沒有拍出來,可能是時間不夠了,卡在第一題上太久,有點悲劇。。。。
A.Rind Road
這題之前把它看成了圖論的題目,沒有看清題意,導致到了比賽前半個鐘頭才寫出來,其實很簡單,題意大概是說,有n個城市和n條單行道,所有的城市通過單行道串連成了一個環,每個單行道都有一個權值c,如果要將單行道改個方向,就要花費c的價錢,現在我們的任務就是花費最小的價錢把n條單行道方向變成同向。
我的方法是將城市看成結點,單行道看成有向邊,建立一個圖,由於n<=100,可以利用鄰接矩陣來儲存,最後從任意一個點出發,正反地跑兩次DFS,如果遇到權值為負的邊(邊的方向和遍曆的方向相反),則把費用加c。最後輸出兩個費用的較小值。
後來想了想,可以只跑一次DFS,然後把權值總和減去第一次的值就是我們第二次DFS得到的值。
我原版的代碼。
#include <cstdio><br />#include <iostream><br />#include <cstring><br />#include <cstdlib><br />#include <algorithm><br />using namespace std;<br />int a[101][2],w1[101][2],total,total1,mark[105];</p><p>void dfs(int u)<br />{<br />int i;<br />mark[u]=1;<br />for(i=0;i<=1;i++)<br />if(!mark[a[u][i]])<br />{<br />if(w1[u][i]<0)<br />total+=(-w1[u][i]);<br />dfs(a[u][i]);<br />}<br />}<br />void dfs1(int u)<br />{<br />int i;<br />mark[u]=1;<br />for(i=1;i>=0;i--)<br />if(!mark[a[u][i]])<br />{<br />if(w1[u][i]<0)<br />total1+=(-w1[u][i]);<br />dfs1(a[u][i]);<br />}<br />}</p><p>int main()<br />{<br />int n,i,x,y,w;</p><p>scanf("%d",&n);</p><p>for(i=0;i<n;i++)<br />{<br />scanf("%d%d%d",&x,&y,&w);<br />if(!a[x][0])<br />{<br />a[x][0]=y;<br />w1[x][0]=w;<br />}<br />else<br />{<br />a[x][1]=y;<br />w1[x][1]=w;<br />}<br />if(!a[y][0])<br />{<br />a[y][0]=x;<br />w1[y][0]=-w;<br />}<br />else<br />{<br />a[y][1]=x;<br />w1[y][1]=-w;<br />}<br />}</p><p>total=0;<br />dfs(1);<br />if(w1[1][1]>0)<br />total+=w1[1][1];<br />memset(mark,0,sizeof(mark));<br />total1=0;<br />dfs1(1);<br />if(w1[1][0]>0)<br />total1+=w1[1][0];<br />if(total1<total)<br />printf("%d/n",total1);<br />else<br />printf("%d/n",total);<br />}<br />
B.F1 Champions
這題是我過的最快的一題,簡單的排序,手寫比較函數就可以了,題目大意是說,F1比賽的冠軍判斷標準有兩種,第一種判斷積分大小,當積分相等的時候判斷獲得第一名的次數,還相等的話,判斷獲得第二的次數,以此類推;第二種判斷獲得第一名的次數,相等,則判斷積分大小,還相等的話和第一種一樣,依次比較第二名、第三名。。。
寫兩個函數比較,分別進行兩次排序,輸出第一名即可。
#include <iostream><br />#include <cstdio><br />#include <cstring><br />#include <cstdlib><br />#include <string><br />#include <map><br />#include <algorithm></p><p>using namespace std;</p><p>const int rate[]={25, 18, 15, 12, 10, 8, 6, 4, 2, 1};<br />struct Node<br />{<br />string name;<br />int point;<br />int rank[51];</p><p>Node()<br />{<br />name="";<br />point=0;<br />memset(rank,0,sizeof(rank));<br />}<br />}node[51];<br />map<string,int> mp;</p><p>bool comp1(const Node& a,const Node& b)<br />{<br />if(a.point!=b.point)<br />return a.point>b.point;<br />for(int i=0;i<51;i++)<br />if(a.rank[i]!=b.rank[i])<br />return a.rank[i]>b.rank[i];</p><p>return a.name<b.name;<br />}</p><p>bool comp2(const Node& a,const Node& b)<br />{<br />if(a.rank[0]!=b.rank[0])<br />return a.rank[0]>b.rank[0];<br />else if(a.point!=b.point)<br />return a.point>b.point;</p><p>for(int i=1;i<51;i++)<br />if(a.rank[i]!=b.rank[i])<br />return a.rank[i]>b.rank[i];</p><p>return a.name<b.name;<br />}</p><p>int main()<br />{<br />int t,n,cnt=0,pos;<br />string name;<br />char str[100];</p><p>scanf("%d",&t);<br />while(t--)<br />{<br />scanf("%d",&n);<br />for(int i=0;i<n;i++)<br />{<br />scanf("%s",str);<br />name=str;<br />if(mp[name]==0)<br />{<br />cnt++;<br />mp[name]=cnt;<br />node[cnt].name=name;<br />}<br />pos=mp[name];<br />node[pos].rank[i]++;<br />if(i<10)<br />node[pos].point+=rate[i];<br />}<br />}</p><p>sort(node+1,node+cnt+1,comp1);<br />printf("%s/n",node[1].name.c_str());<br />sort(node+1,node+cnt+1,comp2);<br />printf("%s/n",node[1].name.c_str());</p><p>return 0;<br />}<br />
C.Sequence of Point
這題比較簡單,比賽的時候寫完代碼測試資料沒過,也沒時間去改,就放棄了,將題意理清之後的到一些公式:
這樣將全部式子加起來,就可以得到完整的公式,由於Ai有周期,我們可以將其模數2n,然後進行計算,為了計算方便,我重載了運算子,封裝了一個點的結構體,其實算是向量了。。。
注意題目給的j奇數偶數的時候M0前面的符號不同
#include <iostream><br />#include <cstdio><br />#include <cstring><br />#include <cstdlib></p><p>using namespace std;</p><p>struct Point<br />{<br />int x;<br />int y;</p><p>Point(int x=0,int y=0)<br />{<br />this->x=x;<br />this->y=y;<br />}<br />Point(const Point& point)<br />{<br />x=point.x;<br />y=point.y;<br />}<br />~Point(){}</p><p>Point operator+(const Point& p){return Point(x+p.x,y+p.y);}<br />Point operator-(const Point& p){return Point(x-p.x,y-p.y);}<br />int operator*(const Point& p){return x*p.x+y*p.y;}<br />void Show(){printf("%d %d/n",x,y);}<br />void Set(const int& x=0,const int& y=0)<br />{<br />this->x=x;<br />this->y=y;<br />}<br />};</p><p>Point m0,a[100100];</p><p>int main()<br />{<br />int n;<br />__int64 k;<br />int x,y;<br />Point ret(0,0);</p><p>scanf("%d%I64d",&n,&k);<br />scanf("%d%d",&x,&y);<br />m0.Set(x,y);<br />for(int i=0;i<n;i++)<br />{<br />scanf("%d%d",&x,&y);<br />a[i].Set(x,y);<br />}</p><p>int len=k%(2*n);<br />bool flag=true;<br />for(int i=0;i<len;i++)<br />{<br />if(flag)<br />ret=ret+a[(k-i-1)%n];<br />else<br />ret=ret-a[(k-i-1)%n];<br />flag=!flag;<br />}<br />ret.x*=2;<br />ret.y*=2;<br />if(k%2)<br />ret=ret-m0;<br />else<br />ret=ret+m0;</p><p>ret.Show();</p><p>return 0;<br />}<br />