2016年4月25日 星期一

(Zj) a871: 11. Museum Area [逆時針排序點,外積]

http://zerojudge.tw/ShowProblem

我的想法是:先把點點按照順or逆時針排序(直接看code比較快),然後取一個定點,算出那個定點和另外兩個連續的點構成的三角形面積。

http://codepad.org/WBmoELb5

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;

const int MAX_N = 12;

struct Point {
 double x;
 double y;
} point[MAX_N];

double cross(Point o,Point a,Point b) {
 return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
}

double dis(Point a,Point b) {
 return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

double get_area(Point a,Point b,Point c) {
 double p = dis(a,b);
 double q = dis(b,c);
 double r = dis(a,c);
 double s = (p+q+r)/2;
 return sqrt(s*(s-p)*(s-q)*(s-r));
}

bool cmp(const Point &p1,const Point &p2) {
 return cross(point[0],p1,p2) < 0.0;
}

int main () {
 int n;
 while (scanf("%d",&n) != EOF) {
  for (int X=0;n>X;X++) {
   double i,j;
   cin >> i >> j;
   point[X].x=i;
   point[X].y=j;
  }
  sort(point+1,point+n,cmp);
  double ans = 0.0;
  for (int x=1;n-1>x;x++) {
   ans+=get_area(point[0],point[x],point[x+1]);
  }
  cout<<fixed<<setprecision(2)<<ans<<endl;
 }
}

2016年4月23日 星期六

(HP Codewar)

HP Codewar 心得:

1. Python好好用
2. 會一直搶電腦
3. 下次參賽要帶兩個來亂的

team : 57
score : 145

(Python) (codeforces) 633A. Ebony and Ivory

http://codeforces.com/contest/633/problem/A

原本想要用dp,在想說用python摳dp滿刺激的。

後來,看到AC人數這麼多,才發現,有夠好的做法~~

枚舉a要多少,就有相對應的b,如果相對應b是合法(不是分數 && >=0),就有答案。

枚舉a時,枚舉0 ~ c

http://codeforces.com/contest/633/submission/17463583

(Python) (codeforces) 50A. Domino piling

http://codeforces.com/problemset/problem/50/A

認真實作即可

http://codeforces.com/contest/50/submission/17463433



(Zj) a870. 10. List Maker

http://zerojudge.tw/ShowProblem?problemid=a870

實作一個Linked-List

找位置(INSERT)的時候用個map

http://codepad.org/4hXztYUM

2016年4月21日 星期四

(Python) (Codeforces) 664B. Rebus

http://codeforces.com/contest/664/problem/B

如果標題有Python,就代表說我是用Python寫的XDDD

其實都可以用C++寫喔

這題的大意是說:給你一個式子,表達成? + ? - ? + ? ....... = n,?的數字必須介於[1,n],可以重複。你的目標是:判斷這個等式可不可以成立,如果成立了,請輸出任意一組解。

例如:? + ? - ? = 3,可以說是2 + 3 - 2 = 3

我的作法:總共會有c1個+,c2個-,對於每個正負,正的最大可以到c1*n,最小的到c1,負的最大可以到c2*n,最小可以到c2,可以創造出來的值就介於c1*n - c2 >= val >= c1 - c2*n。如果這個val可以成立,那我就先是如果正的部分是c1*n,可不可以有相對應的負值,如果有,就輸出(等等再講),沒有的話,那就設定負的部分是c2*n,再去找相對應的正值。

如何輸出呢:先盡可能地接近平均XDDD

http://codeforces.com/contest/664/submission/17419599


2016年4月19日 星期二

(TOJ) 47. 1d-kd-tree

http://sprout.tw/oj/pro/47/

其實這題主要是要讓你實作一棵二元搜尋樹啦,但是我的code不是這樣寫(delete有點麻煩XD)

如果是走二元搜尋樹,insert就是依照key值走下去就對了,query就認真找吧,delete的話,最麻煩的case是要找左子樹的max或右子樹的min。(有點籠統,抱歉~~)

我的離線(off-line)作法是,先把所有數值離散化後,開一棵數值線段樹,記錄說離散化後的這個數字有沒有出現過,沒有的話設成INF,對於每個區間,我要維護說這個區間的Max和Min。

接下來講query的部分,當如果你今天要往左子樹query的時候,右子樹的Min可能是你右邊的答案,往右子樹走的時候,左邊樹的Max可能是你的答案。

所以,綜合一下,就會發現,這題不難XDDD。

(用Treap寫也或許可以,找機會有天來試試看XDDD)

Code :
http://codepad.org/YRd2ghje


(Python) (Codeforces) 1A. Theatre Square

用python寫出來的第一份競賽code ~~~

以後可能考慮python跟c++混用XDDD

Problem :
http://codeforces.com/problemset/problem/1/A

Code :
http://codeforces.com/contest/1/submission/17386721


2016年4月14日 星期四

(Python) Facebook 調查按讚數

其實我也有在寫Python喔~~~

首先要先感謝資訊之芽的講師,class的部分是他們寫

使用方法:先去 http://jupyter.org/ 往下拉找到Try it in your browser,按右邊的New,選Python 3

然後把這段code貼上去 : http://codepad.org/uuQljp4C

在方框裡面,按Shift + Enter,按照上面的作,就可以統計出你fb所有文章中按讚數前十位的朋友名子喔!!!

(codeforces) 463D. Gargari and Permutations

http://codeforces.com/contest/463/problem/D


這題的大意是求五條陣列的LCS,長度1000,數值1~1000

一般的LCS求法是 :
if (n[i] == n[j]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = max(dp[i][j-1] , dp[i-1][j]) ;

那,我們其實可以換個圖論的想法

如果a-->b有可能是LCS的部分,那我們就建個邊

那,在經過k條陣列,如果a-->b總共有k條,那可能是總LCS的一部分

例如:陣列是4,2,1,3,那我們就建(4-->2,4-->1,4-->3,2-->1,2-->3,1-->3)

之後,我們就得到一個DAG,目標就變成求DAG的最長路徑,就很簡單了XDDD

複雜度:O(n^2)

http://codeforces.com/contest/463/submission/17311738

2016年4月4日 星期一

(Zj) a007: 判斷質數

如果數字<10000000,用表格

要不然,用sqrt(n)算法

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <cmath>
using namespace std;
int prime[10000001];
int check_prime[4793];
void build_form()
{
memset(prime,0,sizeof(prime));
//memset(check_prime,0,sizeof(check_prime));
prime[0]=prime[1]=1;
int n=0; //check+prime 用
for (int a=2;46350>a;a++)
{
if (prime[a]==0) //a-->prime
{
if (a>3162) //a^2>400000000
{
;
}
else
{
for (int b=a;10000000>=a*b;b++) prime[a*b]=1;
}
check_prime[n]=a;
n++;
}
}
}
int main ()
{
build_form();
int x;
while (scanf("%d",&x)!=EOF)
{
if (x<=10000000)
{
if (prime[x]==0) puts("質數");
else puts("非質數");
}
else
{
int check=0 , temp=sqrt(x);
for (int y=0;temp>=check_prime[y];y++)
{
if (x%check_prime[y]==0)
{
check=1;
break;
}
}
if (check==1) puts("非質數");
else puts("質數");
}
}
}

(Codeforces) 659E. New Reform

http://codeforces.com/contest/659/problem/E

我覺得這題出的還不錯

我的想法可能不是唯一解,但是可以參考參考。

題目大意是說:給你n座城市m條邊,你要把這m條邊給定方向。我們定義一個城市是separate如果沒有任何一條邊指向他,例如:a-->b, b-->c,a就是separate的城市。

我的想法是:

先用kruscal求出Minimum Spanning Tree(最小生成樹),並且在求出MST的過程中,維護有哪些邊已經用過了(在MST裡面的邊)。

到這個階段,我們已經知道答案最多是 所有子MST數量 + 沒有被邊連到的點。

說明一下為什麼目前的答案是 所有子MST數量 + 沒有被邊連到的點 : 因為MST有n個點,n-1個邊,我隨便找一個點當樹根(root),把樹根當成separate的城市,之後的邊,都指向自己的兒子,這樣就OK了。

之後,對於沒有在MST裡面的邊,我先看說這個邊是在哪個子MST裡面(如果在兩個不同的子MST裡面,那個邊也一定會是MST的邊),如果這個子MST沒有被加邊過,我就把這個邊加到這個MST裡面,這樣答案就可以-1了(想想看,把剛剛當樹根的點設為新邊的其中一個點,那還有新的一條邊可以回到自己)。

這樣就Accepted了。

Code : http://codepad.org/XgOK7d5b


2016年4月2日 星期六

TOI 3月份練習賽 懶人包

題目:

1. Card World : https://www.dropbox.com/s/7wehq59hqwgtjhy/Card%20world.pdf?dl=0
2. Loudspeaker : https://www.dropbox.com/s/2puwdvea84mgmdv/Loudspeaker.pdf?dl=0

第一題Card World :
基本上就是好好實作就好了XDDD
要小心陣列維度處理的問題

code : http://codepad.org/qP23deHx

第二題Loudspeaker :
認真想想,會發現他有二分搜的性質(如果ans可以,那ans+0.1, ans+0.2 ...也一定可以),那當我們確定二分搜可以之後呢,我們就要二分搜答案。

那要怎麼判斷當前距離ans是否可以呢?可以使用greedy的技巧,當現在可以覆蓋的面積沒有辦法覆蓋的pos[i]的家時,那我們就把一個喇叭放在pos[i] + ans的地方,讓覆蓋的距離延伸到pos[i] + 2 * ans

實作上還有一些些小細節,就看code自己想囉!

code : http://codepad.org/iEpS82wC