├── HDU └── 2009.4th_Baidu_Cup_Final │ ├── 2009.4th_Baidu_Cup_Final.Solution_CN.md │ ├── 2289.cpp │ ├── 2290.cpp │ ├── 2292.cpp │ ├── 2293.cpp │ ├── 2295.cpp │ └── 2297.cpp ├── ICPC.Regional.Preliminary ├── 2005.Japan.Domestic │ ├── 2005.Japan.Domestic.Solution_CN.md │ ├── poj2683.cpp │ ├── poj2686.cpp │ ├── poj2687.cpp │ └── poj2688.cpp ├── 2006.Japan.Domestic │ ├── 2006.Japan.Domestic.Solution_CN.md │ ├── img │ │ ├── poj3011_img1.jpg │ │ └── poj3011_img2.jpg │ ├── poj3010.cpp │ └── poj3011.cpp ├── 2007.Japan.Domestic │ ├── 2007.Japan.Domestic.Solution_CN.md │ ├── img │ │ └── poj3229.png │ ├── poj3328.cpp │ ├── poj3329.cpp │ └── poj3330.cpp ├── 2008.Chengdu.Preliminary │ ├── 2008.Chengdu.Preliminary.Solution_CN.md │ ├── hdu2428.cpp │ ├── hdu2429.cpp │ ├── hdu2433.cpp │ ├── hdu2436.cpp │ └── hdu2437.cpp ├── 2008.Harbin.Preliminary │ ├── 2008.Harbin.Preliminary.Solution_CN.md │ ├── hdu2438.cpp │ ├── hdu2440.cpp │ ├── hdu2443.cpp │ ├── hdu2444.cpp │ └── img │ │ └── hdu2438_img1.jpg ├── 2008.Hefei.Preliminary │ ├── 2008.Hefei.Preliminary.Solution_CN.md │ ├── poj3690.cpp │ ├── poj3691.cpp │ ├── poj3692.cpp │ ├── poj3694.cpp │ ├── poj3695.cpp │ └── poj3697.cpp ├── 2008.Nordic │ ├── 2008.Nordic.Solution_CN.md │ ├── uva11555.cpp │ ├── uva11557.cpp │ ├── uva11559.cpp │ ├── uva11561.cpp │ └── uva11562.cpp ├── 2009.Nordic │ ├── 2009.Nordic.Solution_CN.md │ ├── hdu3143.cpp │ ├── hdu3146.cpp │ └── img │ │ └── hdu3146_img1.jpg └── README.md ├── ICPC.Regional ├── 1998.Northeastern_Europe │ ├── 1998.Northeastern_Europe.Solution_CN.md │ ├── la5660.cpp │ ├── la5662.cpp │ └── la5665.cpp ├── 1999.Tehran │ ├── 1999.Tehran.Solution_CN.md │ ├── poj1690.cpp │ ├── poj1692.cpp │ ├── poj1693.cpp │ ├── poj1695.cpp │ └── poj1696.cpp ├── 2000.Tehran │ ├── 2000.Tehran.Solution_CN.md │ ├── la2052.cpp │ ├── la2053.cpp │ ├── la2054.cpp │ ├── la2055.cpp │ ├── la2056.cpp │ ├── la2057.cpp │ ├── la2058.cpp │ ├── la2059.cpp │ └── la2060.cpp ├── 2001.Taejon │ ├── 2001.Taejon.Solution_CN.md │ ├── la2321.cpp │ ├── la2322.cpp │ ├── la2323.cpp │ ├── la2324.cpp │ ├── la2325.cpp │ ├── la2326.cpp │ └── la2328.cpp ├── 2001.Tehran │ ├── 2001.Tehran.Solution_CN.md │ ├── la2338.cpp │ └── la2341.cpp ├── 2002.Kaohsiung │ ├── 2002.Kaohsiung.Solution_CN.md │ ├── poj1339.cpp │ ├── poj1340.cpp │ ├── poj1343.cpp │ └── poj1344.cpp ├── 2003.Guangzhou │ ├── 2003.Guangzhou.Solution_CN.md │ ├── la2948.cpp │ ├── la2951.cpp │ ├── la2953.cpp │ ├── la2954.cpp │ └── la2955.cpp ├── 2004.Shanghai │ ├── 2004.Shanghai.Solution_CN.md │ ├── la3259.cpp │ ├── la3263.cpp │ ├── la3265.cpp │ ├── la3266.cpp │ ├── la3267.cpp │ └── la3268.cpp ├── 2005.Central_Europe │ ├── 2005.Central_Europe.Solution_CN.md │ ├── 3523.cpp │ ├── 3524.cpp │ ├── 3525.cpp │ ├── 3527.cpp │ ├── 3528.cpp │ ├── 3529.cpp │ └── 3531.cpp ├── 2005.Rocky_Mountain │ ├── 2005.Rocky_Mountain.Solution_CN.md │ ├── la3337.cpp │ ├── la3341.cpp │ ├── la3342.cpp │ ├── la3343.cpp │ └── la3344.cpp ├── 2005.Southwestern_Europe │ ├── 2005.Southwestern_Europe.Solution_CN.md │ ├── la3502.cpp │ ├── la3505.cpp │ ├── la3506.cpp │ ├── la3507.cpp │ ├── la3509.cpp │ ├── la3510.cpp │ └── la3511.cpp ├── 2005.Tehran │ ├── 2005.Tehran.Solution_CN.md │ └── la3550.cpp ├── 2005.Tokyo │ ├── 2005.Tokyo.Solution_CN.md │ ├── 3401.cpp │ ├── 3402.cpp │ ├── 3403.cpp │ ├── 3404.cpp │ └── 3405.cpp ├── 2006.Beijing │ ├── 2006.Beijing.Solution_CN.md │ ├── img │ │ └── la3661_img1.jpg │ ├── la3661.cpp │ ├── la3662.cpp │ ├── la3664.cpp │ └── la3667.cpp ├── 2006.Dhaka │ ├── 2006.Dhaka.Solution_CN.md │ ├── la2189.cpp │ ├── la2191.cpp │ ├── la2193.cpp │ └── la2197.cpp ├── 2006.Northeastern_Europe │ ├── 2006.Northeastern_Europe.Solution_CN.md │ ├── img │ │ ├── la3702_img1.jpg │ │ ├── la3702_img2.jpg │ │ └── la3710_img1.jpg │ ├── la3702.cpp │ ├── la3703.cpp │ ├── la3704.cpp │ ├── la3706.cpp │ ├── la3708.cpp │ ├── la3710.cpp │ ├── la3711.cpp │ └── la3712.cpp ├── 2006.Rocky_Mountain │ ├── 2006.Rocky_Mountain.Solution_CN.md │ ├── img │ │ ├── la3582_img1.jpg │ │ ├── la3582_img2.jpg │ │ ├── la3582_img3.jpg │ │ ├── la3582_img4.jpg │ │ └── la3582_img5.jpg │ ├── la3576.cpp │ └── la3582.cpp ├── 2006.Yokohama │ ├── 2006.Yokohama.Solution_CN.md │ ├── 3616.cpp │ ├── 3617.cpp │ ├── 3618.cpp │ ├── 3620.cpp │ ├── 3621.cpp │ ├── 3622.cpp │ ├── 3624.cpp │ └── img │ │ ├── 3618_img1.png │ │ ├── 3618_img2.png │ │ ├── 3618_img3.png │ │ ├── 3618_img4.jpg │ │ └── 3622_img1.jpg ├── 2007.Beijing │ ├── 2007.Beijing.Solution_CN.md │ ├── la4024.cpp │ ├── la4025.cpp │ ├── la4026.cpp │ └── la4032.cpp ├── 2007.Dhaka │ ├── 2007.Dhaka.Solution_CN.md │ ├── la4055.cpp │ ├── la4056.cpp │ ├── la4058.cpp │ ├── la4059.cpp │ ├── la4060.cpp │ ├── la4061.cpp │ ├── la4062.cpp │ └── la4064.cpp ├── 2007.Northwestern_Europe │ ├── 2007.Northwestern_Europe.Solution_CN.md │ ├── img │ │ └── la3975_img1.jpg │ ├── la3971.cpp │ ├── la3972.cpp │ ├── la3973.cpp │ ├── la3975.cpp │ ├── la3976.cpp │ ├── la3977.cpp │ ├── la3978.cpp │ ├── la3979.cpp │ └── la3980.cpp ├── 2007.Seoul │ ├── 2007.Seoul.Solution_CN.md │ ├── la3900.cpp │ ├── la3901.cpp │ ├── la3903.cpp │ ├── la3904.cpp │ ├── la3905.cpp │ └── la3906.cpp ├── 2007.Tokyo │ ├── 2007.Tokyo.Solution_CN.md │ ├── img │ │ ├── 3885_img1.jpg │ │ └── 3886_img1.jpg │ ├── la3882.cpp │ ├── la3883.cpp │ ├── la3884.cpp │ ├── la3885.cpp │ ├── la3886.cpp │ ├── la3887.cpp │ ├── la3888.cpp │ ├── la3890.cpp │ └── la3891.cpp ├── 2008.Aizu │ ├── 2008.Aizu.Solution_CN.md │ ├── 4158.cpp │ └── 4165.cpp ├── 2008.Amritapuri │ ├── 2008.Amritapuri.Solution_CN.md │ ├── la4333.cpp │ ├── la4334.cpp │ ├── la4335.cpp │ ├── la4336.cpp │ ├── la4337.cpp │ └── la4340.cpp ├── 2008.Beijing │ ├── 2008.Beijing.Solution_CN.md │ ├── la4322.cpp │ ├── la4326.cpp │ ├── la4328.cpp │ ├── la4329.cpp │ └── la4330.cpp ├── 2008.Chengdu │ ├── 2008.Chengdu.Solution_CN.md │ ├── la4392.cpp │ ├── la4393.cpp │ ├── la4394.cpp │ ├── la4396.cpp │ ├── la4398.cpp │ ├── la4400.cpp │ └── la4401.cpp ├── 2008.Dhaka │ ├── 2008.Dhaka.Solution_CN.md │ ├── img │ │ └── 4203_Img1.jpg │ ├── la4200.cpp │ ├── la4201.cpp │ ├── la4202.cpp │ ├── la4203.cpp │ ├── la4204.cpp │ ├── la4205.cpp │ ├── la4206.cpp │ ├── la4209.cpp │ └── la4209_2.cpp ├── 2008.Hangzhou │ ├── 2008.Hangzhou.Solution_CN.md │ ├── la4351.cpp │ ├── la4356.cpp │ ├── la4357.cpp │ └── la4360.cpp ├── 2008.Harbin │ ├── 2008.Harbin.Solution_CN.md │ ├── la4314.cpp │ ├── la4319.cpp │ └── la4320.cpp ├── 2008.Hefei │ ├── 2008.Hefei.Solution_CN.md │ ├── img │ │ └── 4275_Img1.jpg │ ├── la4269.cpp │ ├── la4271.cpp │ ├── la4272.cpp │ ├── la4275.cpp │ └── la4276.cpp ├── 2008.Jakarta │ ├── 2008.Jakarta.Solution_CN.md │ ├── la4138.cpp │ ├── la4139.cpp │ ├── la4142.cpp │ ├── la4144.cpp │ ├── la4146.cpp │ └── la4147.cpp ├── 2008.Kuala_Lumpur │ ├── 2008.Kuala_Lumpur.Solution_CN.md │ ├── img │ │ ├── la4413_img1.jpg │ │ ├── la4413_img2.jpg │ │ ├── la4413_img3.jpg │ │ └── la4413_img4.jpg │ ├── la4403.cpp │ ├── la4404.cpp │ ├── la4405.cpp │ ├── la4407.cpp │ ├── la4408.cpp │ ├── la4409.cpp │ └── la4413.cpp ├── 2008.Northwestern_Europe │ ├── 2008.Northwestern_Europe.Solution_CN.md │ ├── 4286.cpp │ ├── 4287.cpp │ ├── 4288.cpp │ ├── 4289.cpp │ ├── 4291.cpp │ ├── 4292.cpp │ ├── 4293.cpp │ ├── 4294.cpp │ └── img │ │ └── 4287_img1.jpg ├── 2008.Southeastern_Europe │ ├── 2008.Southeastern_Europe.Solution_CN.md │ ├── la4183.cpp │ ├── la4184.cpp │ ├── la4185.cpp │ ├── la4187.cpp │ ├── la4188.cpp │ ├── la4189.cpp │ ├── la4190.cpp │ └── la4191.cpp ├── 2008.Southwestern_Europe │ ├── 2008.Southwestern_Europe.Solution_CN.md │ ├── 4296.cpp │ ├── 4297.cpp │ ├── 4298.cpp │ ├── 4299.cpp │ ├── 4302.cpp │ ├── 4303.cpp │ ├── 4304.cpp │ ├── 4305.cpp │ └── img │ │ └── 4303_Img1.jpg ├── 2008.Taipei │ ├── 2008.Taipei.Solution_CN.md │ ├── img │ │ └── la4263_img1.jpg │ ├── la4259.cpp │ ├── la4260.cpp │ ├── la4261.cpp │ ├── la4262.cpp │ ├── la4263.cpp │ ├── la4264.cpp │ ├── la4267.cpp │ └── la4268.cpp ├── 2008.Tehran │ ├── 4423.cpp │ ├── 4423_Solution_CN.md │ ├── 4424.cpp │ ├── 4424_Solution_CN.md │ ├── 4425.cpp │ ├── 4425_Solution_CN.md │ ├── 4426.cpp │ ├── 4426_Solution_CN.md │ ├── 4427.cpp │ ├── 4427_Solution.md │ ├── 4428.cpp │ ├── 4428_Solution_CN.md │ ├── 4429.cpp │ ├── 4429_Solution_CN.md │ ├── 4430.cpp │ ├── 4430_Solution_CN.md │ ├── 4431.cpp │ └── 4431_Solution_CN.md ├── 2008.World_Finals │ ├── 4118.cpp │ ├── 4118_Solution_CN.md │ ├── 4123.cpp │ ├── 4123_Img1.jpg │ ├── 4123_Solution_CN.md │ ├── 4125.cpp │ ├── 4125_Img1.jpg │ ├── 4125_Solution_CN.md │ ├── 4127.cpp │ ├── 4127_Solution_CN.md │ ├── 4128.cpp │ └── 4128_Solution_CN.md ├── 2009.Amritapuri │ ├── 4676.cpp │ ├── 4676_Solution_CN.md │ ├── 4677.cpp │ ├── 4677_Solution_CN.md │ ├── 4680.cpp │ ├── 4680_Solution_CN.md │ ├── 4681.cpp │ ├── 4681_Solution_CN.md │ ├── 4682.cpp │ ├── 4682_Solution_CN.md │ ├── 4683.cpp │ ├── 4683_Solution.md │ ├── 4684.cpp │ ├── 4684_Solution_CN.md │ ├── 4685.cpp │ └── 4685_Solution_CN.md ├── 2009.Dhaka │ ├── 2009.Dhaka.Solution_CN.md │ ├── 4493.cpp │ ├── 4494.cpp │ ├── 4495.cpp │ ├── 4496.cpp │ ├── 4497.cpp │ ├── 4499.cpp │ ├── 4500.cpp │ ├── 4502.cpp │ └── img │ │ └── 4500_Img1.jpg ├── 2009.Harbin │ ├── 2009.Harbin.Solution_CN.md │ ├── la4764.cpp │ ├── la4766.cpp │ ├── la4769.cpp │ ├── la4770.cpp │ ├── la4772.cpp │ └── la4773.cpp ├── 2009.Hefei │ ├── 2009.Hefei.Solution_CN.md │ ├── 4666.cpp │ ├── 4667.cpp │ ├── 4669.cpp │ ├── 4670.cpp │ ├── 4670_2.cpp │ └── 4672.cpp ├── 2009.Ningbo │ ├── 2009.Ningbo.Solution_CN.md │ ├── la4755.cpp │ ├── la4756.cpp │ ├── la4757.cpp │ ├── la4758.cpp │ ├── la4759.cpp │ ├── la4761.cpp │ └── la4762.cpp ├── 2009.Northwestern_Europe │ ├── 2009.Northwestern_Europe.Solution_CN.md │ ├── img │ │ └── 4617_Img1.jpg │ ├── la4609.cpp │ ├── la4610.cpp │ ├── la4611.cpp │ ├── la4612.cpp │ ├── la4613.cpp │ ├── la4614.cpp │ ├── la4616.cpp │ └── la4617.cpp ├── 2009.Phuket │ ├── 2009.Phuket.Solution_CN.md │ ├── img │ │ ├── la4714_img1.jpg │ │ └── la4714_img2.jpg │ ├── la4712.cpp │ ├── la4713.cpp │ ├── la4714.cpp │ ├── la4716.cpp │ └── la4721.cpp ├── 2009.Shanghai │ ├── 2009.Shanghai.Solution_CN.md │ ├── img │ │ └── la4750_img1.jpg │ ├── la4743.cpp │ ├── la4744.cpp │ ├── la4745.cpp │ ├── la4747.cpp │ ├── la4750.cpp │ ├── la4751.cpp │ └── la4752.cpp ├── 2009.Southwestern_Europe │ ├── 2009.Southwestern_Europe.Solution_CN.md │ ├── la4504.cpp │ ├── la4505.cpp │ ├── la4507.cpp │ ├── la4507_2.cpp │ ├── la4509.cpp │ ├── la4510.cpp │ ├── la4512.cpp │ └── la4513.cpp ├── 2009.Wuhan │ ├── 2009.Wuhan.Solution_CN.md │ ├── la4484.cpp │ ├── la4485.cpp │ ├── la4486.cpp │ ├── la4487.cpp │ ├── la4489.cpp │ └── la4492.cpp ├── 2010.East_Central_NA │ ├── 2010.East_Central_NA.Solution_CN.md │ ├── la4900.cpp │ ├── la4901.cpp │ ├── la4902.cpp │ └── la4905.cpp ├── 2010.Hangzhou │ ├── 2010.Hangzhou.Solution_CN.md │ ├── la4834.cpp │ ├── la4835.cpp │ ├── la4838.cpp │ ├── la4840.cpp │ └── la4842.cpp ├── 2010.Tokyo │ ├── 5067.cpp │ ├── 5067_Solution_CN.md │ ├── 5068.cpp │ ├── 5068_Solution_CN.md │ ├── 5069.cpp │ ├── 5069_Solution_CN.md │ ├── 5070.cpp │ ├── 5070_Solution_CN.md │ ├── 5071.cpp │ ├── 5071_Solution_CN.md │ ├── 5072.cpp │ ├── 5072_Solution_CN.md │ ├── 5074.cpp │ ├── 5074_Solution_CN.md │ ├── 5075.cpp │ ├── 5075_2.cpp │ └── 5075_Solution_CN.md └── README.md ├── POJ ├── README.md ├── img │ ├── poj3558.jpg │ ├── poj3675_1.jpg │ ├── poj3675_2.jpg │ ├── poj3675_3.jpg │ └── poj3675_4.jpg ├── poj1662.pas ├── poj1830.Solution_CN.md ├── poj1830.cpp ├── poj2096.Solution_CN.md ├── poj2096.cpp ├── poj2928.Solution_CN.md ├── poj2928.cpp ├── poj2932.Solution_CN.md ├── poj2932.cpp ├── poj3029.Solution_CN.md ├── poj3029.cpp ├── poj3033.Solution_CN.md ├── poj3033.cpp ├── poj3034.Solution_CN.md ├── poj3034.cpp ├── poj3035.Solution_CN.md ├── poj3035.cpp ├── poj3036.cpp ├── poj3225.Solution_CN.md ├── poj3225.cpp ├── poj3301.Solution_CN.md ├── poj3301.cpp ├── poj3528.Solution_CN.md ├── poj3528.cpp ├── poj3532.Solution_CN.md ├── poj3532.cpp ├── poj3558.Solution_CN.md ├── poj3558.cpp ├── poj3562.Solution_CN.md ├── poj3562.cpp ├── poj3675.Solution_CN.md ├── poj3675.cpp ├── poj3713.Solution_CN.md ├── poj3713.cpp ├── poj3715.Solution_CN.md ├── poj3715.cpp ├── poj3723.Solution_CN.md ├── poj3723.cpp ├── poj3724.Solution_CN.md ├── poj3724.cpp ├── poj3728.Solution_CN.md ├── poj3728.cpp ├── poj3729.Solution_CN.md ├── poj3729.cpp ├── poj3732.Solution_CN.md ├── poj3732.cpp ├── poj3734.Solution_CN.md ├── poj3734.cpp ├── poj3739.Solution_CN.md └── poj3739.cpp ├── README.md ├── SGU ├── 110.Solution_CN.md ├── 110.cpp ├── 131.Solution_CN.md ├── 131.cpp ├── 142.Solution_CN.md ├── 142.cpp ├── 149.Solution_CN.md ├── 149.cpp ├── 174.Solution_CN.md ├── 174.cpp ├── 177.Solution_CN.md ├── 177.cpp ├── 193.Solution_CN.md ├── 193.pas ├── 222.Solution_CN.md ├── 222.cpp ├── 224.Solution_CN.md ├── 224.pas ├── 297.Solution_CN.md ├── 297.pas ├── 299.Solution_CN.md ├── 299.cpp ├── 332.Solution_CN.md └── 332.cpp └── World_Finals ├── 2005.World_Finals ├── la3270.cpp ├── la3271.cpp ├── la3274.cpp ├── la3276.cpp └── la3278.cpp ├── 2007.World_Finals ├── la2395.cpp ├── la3736.cpp ├── la3752.cpp └── la3807.cpp ├── 2008.World_Finals ├── 2008.World_Finals.Solution_CN.md ├── img │ ├── la4123_img1.jpg │ └── la4125_img1.jpg ├── la4118.cpp ├── la4123.cpp ├── la4125.cpp ├── la4127.cpp └── la4128.cpp ├── 2009.World_Finals ├── 4445_Solution_CN.md ├── 4446_Solution_CN.md ├── 4448_Solution_CN.md ├── 4450_Solution_CN.md ├── 4452_Solution_CN.md ├── 4453_Solution_CN.md ├── la4445.cpp ├── la4446.cpp ├── la4448.cpp ├── la4450.cpp ├── la4452.cpp └── la4453.cpp ├── 2010.World_Finals ├── 4787_Solution_CN.md ├── 4788_Solution_CN.md ├── la4787.cpp └── la4788.cpp └── 2011.World_Finals ├── 5130_Solution_CN.md ├── 5138_Solution_CN.md ├── la5130.cpp └── la5138.cpp /HDU/2009.4th_Baidu_Cup_Final/2289.cpp: -------------------------------------------------------------------------------- 1 | // HDU 2289 2 | // The 4th Baidu Cup Final: Cup 3 | #include 4 | #include 5 | double R, r, H, v1, th; 6 | #define PI 3.14159265358979323846 7 | double getv(double h) { 8 | double rr; 9 | double ans; 10 | rr = (th + h) * r / th; 11 | ans = PI * rr * rr * (h + th) / 3.0 - v1; 12 | return ans; 13 | } 14 | 15 | void solve() { 16 | double left, right, mid, V, ans; 17 | scanf("%lf%lf%lf%lf", &r, &R, &H, &V); 18 | if (r == R) { 19 | ans = V / (r * r * PI); 20 | if(ans > H) 21 | ans = H; 22 | printf("%.6lf\n", ans); 23 | return; 24 | } 25 | left = 0, right = H; 26 | th = r * H / (R - r); 27 | v1 = PI * r * r * th / 3.0; 28 | while (right - left > 1e-8) { 29 | mid = (left + right) / 2.0; 30 | double co = getv(mid); 31 | if(fabs(co - V) < 1e-7) 32 | { 33 | printf("%.6lf\n", mid); 34 | return; 35 | } 36 | if (co > V) right = mid; 37 | else left = mid; 38 | } 39 | printf("%.6lf\n", right); 40 | } 41 | int main() { 42 | int T; 43 | scanf("%d", &T); 44 | while (T--) 45 | solve(); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /HDU/2009.4th_Baidu_Cup_Final/2292.cpp: -------------------------------------------------------------------------------- 1 | // HDU 2292 2 | // The 4th Baidu Cup Final: Minimum Heap 3 | #include 4 | #include 5 | using namespace std; 6 | #define N 1005 7 | long long dp[N], tree[N*2], c[N][N], lc[N], rc[N], m; 8 | void make(int n) { 9 | int i, j; 10 | memset(tree, 0, sizeof(tree)); 11 | for (i = n; i >= 1; i--) { 12 | tree[i]++; 13 | tree[i] += tree[i * 2]; 14 | tree[i] += tree[i * 2 + 1]; 15 | } 16 | for (i = 0; i <= n; i++) { 17 | c[i][0] = 1; 18 | for (j = 1; j <= n; j++) 19 | c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % m; 20 | } 21 | for (i = 1; i <= n; i++) 22 | lc[tree[i]] = tree[i * 2], rc[tree[i]] = tree[i * 2 + 1]; 23 | } 24 | 25 | long long f(long long x) { 26 | if (dp[x] != -1) return dp[x]; 27 | return dp[x] = (((f(lc[x]) * f(rc[x])) % m) * c[x - 1][lc[x]]) % m; 28 | } 29 | int main() { 30 | int T; 31 | long long n; 32 | scanf("%d", &T); 33 | while (T--) { 34 | memset(dp, -1, sizeof(dp)); 35 | dp[0] = dp[1] = dp[2] = 1, dp[3] = 2; 36 | scanf("%lld%lld", &n, &m); 37 | make(n); 38 | printf("%lld\n", f(n) % m); 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2005.Japan.Domestic/poj2683.cpp: -------------------------------------------------------------------------------- 1 | // 2005 Japan Domestic: Ohgas' Fortune 2 | // POJ 2683 3 | #include 4 | double rate; 5 | int base, year, cut; 6 | int comp() { 7 | int i, ans = base; 8 | for (i = 1; i <= year; i++) 9 | ans = (int) ((double) ans * (rate + 1)) - cut; 10 | return ans; 11 | } 12 | 13 | int single() { 14 | int sumrate = 0, i, ans = base; 15 | for (i = 1; i <= year; i++) { 16 | sumrate += (int) ((double) ans * rate); 17 | ans -= cut; 18 | } 19 | return ans + sumrate; 20 | 21 | } 22 | int main() { 23 | int T, op, i, max; 24 | scanf("%d", &T); 25 | while (T--) { 26 | max = 0; 27 | scanf("%d%d%d", &base, &year, &op); 28 | for (i = 0; i < op; i++) { 29 | int c_s, t; 30 | scanf("%d%lf%d", &c_s, &rate, &cut); 31 | t = c_s ? comp() : single(); 32 | if (t > max) 33 | max = t; 34 | } 35 | printf("%d\n", max); 36 | } 37 | return 0; 38 | } 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2006.Japan.Domestic/img/poj3011_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional.Preliminary/2006.Japan.Domestic/img/poj3011_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2006.Japan.Domestic/img/poj3011_img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional.Preliminary/2006.Japan.Domestic/img/poj3011_img2.jpg -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2007.Japan.Domestic/img/poj3229.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional.Preliminary/2007.Japan.Domestic/img/poj3229.png -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Chengdu.Preliminary/hdu2428.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Chengdu Preliminary: Stars 2 | // HDU 2428 3 | 4 | #include 5 | #include 6 | #include 7 | #define M 50001 8 | using namespace std; 9 | map m[M]; 10 | 11 | struct POINT { 12 | int x, y; 13 | POINT(int x, int y) : 14 | x(x), y(y) { 15 | } 16 | POINT() : 17 | x(0), y(0) { 18 | } 19 | }; 20 | POINT q[M]; 21 | 22 | int main() { 23 | int n, T; 24 | scanf("%d", &T); 25 | while (T--) { 26 | scanf("%d", &n); 27 | for (int i = 0; i < M; i++) 28 | m[i].clear(); 29 | for (int i = 0; i < n; i++) { 30 | int a, b; 31 | scanf("%d%d", &a, &b); 32 | m[a + 10001][b] = 1; 33 | q[i] = POINT(a + 10001, b); 34 | } 35 | int ans = 0; 36 | for (int i = 0; i < n; i++) { 37 | for (int j = i + 1; j < n; j++) { 38 | int x1 = q[i].x, y1 = q[i].y; 39 | int x2 = q[j].x, y2 = q[j].y; 40 | int x3 = x1, y3 = y2, x4 = x2, y4 = y1; 41 | if (y2 - y1 != x2 - x1) 42 | continue; 43 | if (m[x3].find(y3) != m[x3].end() && m[x4].find(y4) != m[x4].end()) 44 | ans++; 45 | } 46 | } 47 | printf("%d\n", ans); 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Chengdu.Preliminary/hdu2436.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Chengdu Preliminary: Collision Detection 2 | // HDU 2436 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int ks; 9 | int x, y, z; 10 | int cx, cy, cz, r; 11 | int xt, yt, zt; 12 | int minX, maxX, minY, maxY, minZ, maxZ; 13 | 14 | void in() { 15 | scanf("%d%d%d", &xt, &yt, &zt); 16 | minX = maxX = xt; 17 | minY = maxY = yt; 18 | minZ = maxZ = zt; 19 | for (int j = 0; j < 7; ++j) { 20 | scanf("%d%d%d", &xt, &yt, &zt); 21 | minX = min(minX, xt); 22 | maxX = max(maxX, xt); 23 | minY = min(minY, yt); 24 | maxY = max(maxY, yt); 25 | minZ = min(minZ, zt); 26 | maxZ = max(maxZ, zt); 27 | } 28 | scanf("%d%d%d%d", &cx, &cy, &cz, &r); 29 | } 30 | 31 | void getxyz() { 32 | x = cx, y = cy, z = cz; 33 | 34 | if (x < minX) 35 | x = minX; 36 | else if (x > maxX) 37 | x = maxX; 38 | 39 | if (y < minY) 40 | y = minY; 41 | else if (y > maxY) 42 | y = maxY; 43 | 44 | if (z < minZ) 45 | z = minZ; 46 | else if (z > maxZ) 47 | z = maxZ; 48 | } 49 | 50 | long long getdis() { 51 | return (long long) (x - cx) * (x - cx) + (long long) (y - cy) * (y - cy) + (long long) (z - cz) * (z - cz); 52 | } 53 | 54 | int main() { 55 | scanf("%d", &ks); 56 | for (int i = 0; i < ks; ++i) { 57 | in(); 58 | getxyz(); 59 | if ((long long) r * r >= getdis()) 60 | printf("Yes\n"); 61 | else 62 | printf("No\n"); 63 | } 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Chengdu.Preliminary/hdu2437.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Chengdu Preliminary: Jerboas 2 | // HDU 2437 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 1005 9 | struct EDGE { 10 | int b, w; 11 | EDGE() { } 12 | EDGE(int b, int w) : b(b), w(w) { } 13 | }; 14 | vector G[N]; 15 | int dp[N][N], n, m, s, k; 16 | bool ok[N]; 17 | 18 | void dfs(int x, int v) { 19 | for (int i = 0; i < (int) G[x].size(); i++) { 20 | int d = (v + G[x][i].w) % k; 21 | int p = G[x][i].b; 22 | if (dp[p][d] == -1 || v + G[x][i].w < dp[p][d]) { 23 | dp[p][d] = v + G[x][i].w; 24 | dfs(p, v + G[x][i].w); 25 | } 26 | } 27 | } 28 | 29 | void solve() { 30 | int a, b, w, i, ans, best; 31 | scanf("%d%d%d%d\n", &n, &m, &s, &k); 32 | for (i = 1; i <= n; i++) { 33 | ok[i] = (getchar() == 'P'); 34 | G[i].clear(); 35 | } 36 | while (m--) { 37 | scanf("%d%d%d", &a, &b, &w); 38 | G[a].push_back(EDGE(b, w)); 39 | } 40 | memset(dp, -1, sizeof(dp)); 41 | dfs(s, 0); 42 | ans = best = -1; 43 | for (i = 1; i <= n; i++) 44 | if (ok[i] && dp[i][0] != -1 && (ans == -1 || dp[i][0] < ans)) 45 | best = i, ans = dp[i][0]; 46 | printf("%d %d\n", ans, best); 47 | } 48 | 49 | int main() { 50 | int T, ca = 1; 51 | scanf("%d\n", &T); 52 | while (T--) { 53 | printf("Case %d: ", ca++); 54 | solve(); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Harbin.Preliminary/hdu2438.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Harbin Preliminary: Turn the corner 2 | // HDU 2438 3 | 4 | #include 5 | #include 6 | #define PI 3.14159265358 7 | #define EPS 0.0005 8 | double X, Y, D, L; 9 | 10 | double f(double x) { 11 | return -(cos(x) / sin(x) * X - L * cos(x) - D / sin(x)); 12 | } 13 | 14 | double solve() { 15 | double l, r, m, mm; 16 | l = 0.00001, r = PI / 2; 17 | while (l + EPS < r) { 18 | m = (l + r) / 2; 19 | mm = (m + r) / 2; 20 | if (f(m) >= f(mm)) r = mm; 21 | else l = m; 22 | } 23 | return f(m); 24 | } 25 | 26 | int main() { 27 | while (~scanf("%lf%lf%lf%lf", &X, &Y, &L, &D)) { 28 | int ok = 1; 29 | if (D > X || D > Y) ok = 0; 30 | if (ok) if (solve() > Y) ok = 0; 31 | puts(ok ? "yes" : "no"); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Harbin.Preliminary/hdu2443.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Harbin Preliminary: Counter Strike 2 | // HDU 2443 3 | 4 | #include 5 | #define N 100005 6 | __int64 a[N], b[N], change; 7 | void merge(int l, int m, int r) { 8 | int i = 0, j, ba, bb, ea, eb; 9 | ba = l, ea = m, bb = m + 1, eb = r; 10 | while (ba <= ea && bb <= eb) { 11 | if (a[ba] <= a[bb]) 12 | b[i++] = a[ba++]; 13 | else { 14 | b[i++] = a[bb++]; 15 | change += ea - ba + 1; 16 | } 17 | } 18 | for (; ba <= ea; ba++) 19 | b[i++] = a[ba]; 20 | for (; bb <= eb; bb++) 21 | b[i++] = a[bb]; 22 | for (j = 0; j < i; j++) 23 | a[l + j] = b[j]; 24 | } 25 | void mergesort(int l, int r) { 26 | if (r > l) { 27 | int mid = (l + r) / 2; 28 | mergesort(l, mid); 29 | mergesort(mid + 1, r); 30 | merge(l, mid, r); 31 | } 32 | } 33 | int main() { 34 | int T; 35 | scanf("%d", &T); 36 | while (T--) { 37 | int i, n, x; 38 | scanf("%d%d", &n, &x); 39 | a[n] = 0; 40 | for (i = 0; i < n; i++) 41 | scanf("%I64d", a + i); 42 | for (i = n - 1; i >= 0; i--) 43 | a[i] = a[i] + a[i + 1] - x; 44 | change = 0; 45 | mergesort(0, n); 46 | printf("%I64d\n", change); 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Harbin.Preliminary/img/hdu2438_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional.Preliminary/2008.Harbin.Preliminary/img/hdu2438_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Hefei.Preliminary/poj3690.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hefei Preliminary: Constellations 2 | // POJ 3690 3 | #include 4 | #define M 1003 5 | #define N 55 6 | long long mask[N], st[M][M]; 7 | int n, m, t, p, q; 8 | void init() { 9 | mask[1] = 1; 10 | for (int i = 2; i <= 51; i++) 11 | mask[i] = (mask[i - 1] << 1) + 1; 12 | } 13 | int solve() { 14 | int i, j, k, ans = 0, fail; 15 | for (i = 1; i <= n; i++) { 16 | getchar(); 17 | st[i][1] = 0; 18 | for (j = 1; j <= q; j++) 19 | st[i][1] = (st[i][1] << 1) + (getchar() == '*'); 20 | for (k = 2; j <= m; j++, k++) 21 | st[i][k] = ((st[i][k - 1] << 1) + (getchar() == '*')) & mask[q]; 22 | 23 | } 24 | while (t--) { 25 | long long mt[N]; 26 | getchar(); 27 | for (i = 1; i <= p; i++) 28 | for (getchar(), j = 1, mt[i] = 0; j <= q; j++) 29 | mt[i] = (mt[i] << 1) + (getchar() == '*'); 30 | 31 | for (i = 1; i <= n - p + 1; i++) 32 | for (j = 1; j <= m - q + 1; j++) { 33 | fail = 0; 34 | for (k = 0; k < p; k++) 35 | if (st[i + k][j] != mt[k + 1]) { 36 | fail = 1; 37 | break; 38 | } 39 | if (!fail) 40 | goto out; 41 | } 42 | out: ans += !fail; 43 | } 44 | return ans; 45 | } 46 | 47 | int main() { 48 | int T = 0; 49 | init(); 50 | while (scanf("%d%d%d%d%d", &n, &m, &t, &p, &q) && p) 51 | printf("Case %d: %d\n", ++T, solve()); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Hefei.Preliminary/poj3692.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hefei Preliminary: Kindergarten 2 | // POJ 3692 3 | #include 4 | #include 5 | #define N 500 6 | 7 | int g[N][N], v[N], link[N], color[N], nl, nr; 8 | int n, m; 9 | 10 | // Maximum matching in bipartite graph 11 | int dfs(int t) { 12 | int i; 13 | for (i = 1; i <= nr; i++) { 14 | if (!v[i] && g[t][i]) { 15 | v[i] = 1; 16 | if (link[i] == -1 || dfs(link[i])) { 17 | link[i] = t; 18 | return 1; 19 | } 20 | } 21 | } 22 | return 0; 23 | } 24 | 25 | int main() { 26 | int i, j, a, b, ng, nb, m, T = 1; 27 | while (scanf("%d%d%d", &ng, &nb, &m) && ng + nb + m) { 28 | int ans = 0; 29 | memset(g, 0, sizeof(g)); 30 | for (i = 0; i < m; i++) { 31 | scanf("%d%d", &a, &b); 32 | g[a][ng + b] = g[ng + b][a] = 1; 33 | } 34 | for (i = 1; i <= ng; i++) 35 | for (j = 1; j <= ng; j++) 36 | g[i][j] = 1; 37 | for (i = 1; i <= nb; i++) 38 | for (j = 1; j <= nb; j++) 39 | g[ng + i][ng + j] = 1; 40 | nl = nr = ng + nb; 41 | for (i = 1; i <= nl; i++) { 42 | for (j = 1; j <= nl; j++) 43 | g[i][j] = !g[i][j]; 44 | g[i][i] = 0; 45 | } 46 | memset(link, -1, sizeof(link)); 47 | memset(v, 0, sizeof(v)); 48 | for (i = 1; i <= nl; i++) { 49 | memset(v, 0, sizeof(v)); 50 | ans += dfs(i); 51 | } 52 | printf("Case %d: %d\n", T++, nl - ans / 2); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Hefei.Preliminary/poj3697.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hefei Preliminary: USTC campus network 2 | // POJ 3697 3 | #include 4 | #include 5 | #include 6 | #define N 10006 7 | using namespace std; 8 | int used[N]; 9 | vector G[N]; 10 | int solve(int n) { 11 | vector v; 12 | int i, j, ans = 0, nt; 13 | v.push_back(1); 14 | used[1] = 1; 15 | while (1) { 16 | int notgo[N]; 17 | for (i = 0; i <= n; i++) 18 | notgo[i] = 0; 19 | for (i = 0; i < v.size(); i++) 20 | for (j = 0; j < G[v[i]].size(); j++) 21 | notgo[G[v[i]][j]]++; 22 | nt = v.size(); 23 | v.clear(); 24 | for (i = 1; i <= n; i++) 25 | if (!used[i] && notgo[i] != nt) 26 | used[i] = 1, v.push_back(i), ans++; 27 | if (v.size() == 0) 28 | return ans; 29 | } 30 | } 31 | 32 | int main() { 33 | int T = 0, i, a, b, m, n; 34 | while (scanf("%d%d", &n, &m) && n) { 35 | memset(used, 0, sizeof(used)); 36 | for (i = 0; i <= n; i++) 37 | G[i].clear(); 38 | for (i = 0; i < m; i++) { 39 | scanf("%d%d", &a, &b); 40 | G[a].push_back(b), G[b].push_back(a); 41 | } 42 | printf("Case %d: %d\n", ++T, solve(n)); 43 | } 44 | return 0; 45 | } -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Nordic/uva11555.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Nordic: Aspen Avenue 2 | // UVA 11555 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 2005 9 | 10 | double pos[N]; 11 | double dp[N][N]; 12 | double sqr(double x) { 13 | return x * x; 14 | } 15 | double dis(double x1, double y1, double x2, double y2) { 16 | return sqrt(sqr(x1 - x2) + sqr(y1 - y2)); 17 | } 18 | int main() { 19 | int n, i, j; 20 | double w, l; 21 | while (scanf("%d%lf%lf", &n, &l, &w) != EOF) { 22 | double dy = l / (n / 2 - 1); 23 | for (i = 1; i <= n; i++) 24 | scanf("%lf", &pos[i]); 25 | sort(pos + 1, pos + 1 + n); 26 | dp[0][0] = 0; 27 | for (i = 1; i <= n / 2; i++) { 28 | double x1, y1, x2, y2; 29 | x1 = 0, y1 = pos[i]; 30 | x2 = w, y2 = dy * (i - 1); 31 | dp[i][0] = dp[i - 1][0] + dis(x1, y1, x2, y2); 32 | x2 = 0, y2 = dy * (i - 1); 33 | dp[i][i] = dp[i - 1][i - 1] + dis(x1, y1, x2, y2); 34 | } 35 | for (i = 2; i <= n; i++) { 36 | for (j = 1; j < min(i, n / 2 + 1); j++) { 37 | double a1, a2, x1, y1, x2, y2; 38 | x1 = 0, y1 = pos[i]; 39 | x2 = w, y2 = dy * (i - j - 1); 40 | a1 = dp[i - 1][j] + dis(x1, y1, x2, y2); 41 | x2 = 0, y2 = dy * (j - 1); 42 | a2 = dp[i - 1][j - 1] + dis(x1, y1, x2, y2); 43 | dp[i][j] = min(a1, a2); 44 | } 45 | } 46 | printf("%.8lf\n", dp[n][n / 2]); 47 | } 48 | return 0; 49 | } -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Nordic/uva11559.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Nordic: Event Planning 2 | // UVA 11559 3 | #include 4 | #define N 25 5 | int price[N], a[N][N]; 6 | int main() { 7 | int n, b, h, w, i, j; 8 | while (scanf("%d%d%d%d", &n, &b, &h, &w) != EOF) { 9 | int best = b, ok = 0; 10 | for (i = 0; i < h; i++) { 11 | scanf("%d", &price[i]); 12 | for (j = 0; j < w; j++) { 13 | scanf("%d", &a[i][j]); 14 | if (a[i][j] >= n && price[i] * n <= best) best = price[i] * n, ok = 1; 15 | } 16 | } 17 | if (ok) printf("%d\n", best); 18 | else printf("stay home\n"); 19 | } 20 | return 0; -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2008.Nordic/uva11561.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Nordic: Getting Gold 2 | // UVA 11561 3 | #include 4 | #include 5 | #define N 60 6 | 7 | char map[N][N]; 8 | int dx[] = { 0, 1, 0, -1 }; 9 | int dy[] = { 1, 0, -1, 0 }; 10 | struct NODE { 11 | int x, y; 12 | NODE() { 13 | } 14 | NODE(int x, int y) : 15 | x(x), y(y) { 16 | } 17 | }; 18 | NODE Q[N * N * 2]; 19 | bool vis[N][N]; 20 | int main() { 21 | int i, w, h, j; 22 | while (scanf("%d%d", &w, &h) != EOF) { 23 | NODE st; 24 | for (i = 0; i < h; i++) { 25 | scanf("%s", map[i]); 26 | for (j = 0; j < w; j++) 27 | if (map[i][j] == 'P') st = NODE(i, j); 28 | } 29 | int ans = 0, qh = 0, qe = 0; 30 | Q[qe++] = st; 31 | memset(vis, 0, sizeof(vis)); 32 | vis[st.x][st.y] = 0; 33 | while (qh < qe) { 34 | NODE top = Q[qh++]; 35 | if (map[top.x][top.y] == 'G') ans++; 36 | int ok = 1, nx, ny; 37 | for (i = 0; i < 4; i++) { 38 | nx = top.x + dx[i], ny = top.y + dy[i]; 39 | if (nx < 0 || ny < 0 || nx == h || ny == w) continue; 40 | if (map[nx][ny] == 'T') ok = 0; 41 | } 42 | if (ok == 0) continue; 43 | for (i = 0; i < 4; i++) { 44 | nx = top.x + dx[i], ny = top.y + dy[i]; 45 | if (nx < 0 || ny < 0 || nx == h || ny == w) continue; 46 | if (!vis[nx][ny] && map[nx][ny] != '#') { 47 | Q[qe++] = NODE(nx, ny); 48 | vis[nx][ny] = 1; 49 | } 50 | } 51 | } 52 | printf("%d\n", ans); 53 | } 54 | return 0; 55 | } -------------------------------------------------------------------------------- /ICPC.Regional.Preliminary/2009.Nordic/img/hdu3146_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional.Preliminary/2009.Nordic/img/hdu3146_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/1998.Northeastern_Europe/la5660.cpp: -------------------------------------------------------------------------------- 1 | // 1998 Northeastern Europe: Fence 2 | // ACM-ICPC Live Archive 5660 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | const double PI = 3.141592653589793238462643383; 10 | const int N = 100 + 5; 11 | 12 | struct POINT { 13 | double x, y; 14 | }; 15 | POINT poly[N]; 16 | 17 | double getAngle(int i1, int i2) { 18 | double a = atan2(poly[i1].x, poly[i1].y) - atan2(poly[i2].x, poly[i2].y); 19 | if (a > PI) a -= 2 * PI; 20 | if (a < -PI) a += 2 * PI; 21 | return a; 22 | } 23 | 24 | void solve() { 25 | double k, h; 26 | int n; 27 | scanf("%lf%lf%d", &k, &h, &n); 28 | 29 | for (int i = 0; i < n; i++) 30 | scanf("%lf%lf", &poly[i].x, &poly[i].y); 31 | poly[n] = poly[0]; 32 | 33 | double sum = 0, mina = 0, maxa = 0; 34 | for (int i = 0; i < n; i++){ 35 | sum += getAngle(i, i + 1); 36 | mina = min(sum, mina); 37 | maxa = max(sum, maxa); 38 | } 39 | 40 | printf("%.2lf\n", k * h * min(2 * PI, maxa - mina)); 41 | } 42 | 43 | int main(){ 44 | int T; 45 | scanf("%d", &T); 46 | for (int ca = 0; ca < T; ca++){ 47 | if (ca) printf("\n"); 48 | solve(); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /ICPC.Regional/1998.Northeastern_Europe/la5665.cpp: -------------------------------------------------------------------------------- 1 | // 1998 Northeastern Europe: Gangsters 2 | // ACM-ICPC Live Archive 5665 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define N 105 9 | struct GANE { 10 | int t, p, s; 11 | }; 12 | 13 | int cmp(const void* a, const void* b) { 14 | return ((GANE*) a)->t - ((GANE*) b)->t; 15 | } 16 | 17 | void solve() { 18 | int n, t, k, i, j, g[N], ans = 0; 19 | GANE list[N]; 20 | scanf("%d%d%d", &n, &k, &t); 21 | for (i = 0; i < n; i++) 22 | scanf("%d", &list[i].t); 23 | for (i = 0; i < n; i++) 24 | scanf("%d", &list[i].p); 25 | for (i = 0; i < n; i++) 26 | scanf("%d", &list[i].s); 27 | qsort(list, n, sizeof(list[0]), cmp); 28 | 29 | for (i = 0; i < n; i++) { 30 | g[i] = -1; 31 | if (list[i].t >= list[i].s) 32 | g[i] = 0; 33 | for (j = 0; j < i; j++) 34 | if (abs(list[i].s - list[j].s) <= (list[i].t - list[j].t) && g[i] < g[j]) 35 | g[i] = g[j]; 36 | if (g[i] >= 0) 37 | g[i] += list[i].p; 38 | } 39 | for (i = 0; i < n; i++) 40 | if (g[i] > ans) 41 | ans = g[i]; 42 | printf("%d\n", ans); 43 | } 44 | 45 | int main(){ 46 | int T; 47 | scanf("%d", &T); 48 | for(int ca = 0; ca < T;ca++){ 49 | if(ca) printf("\n"); 50 | solve(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ICPC.Regional/1999.Tehran/poj1690.cpp: -------------------------------------------------------------------------------- 1 | // 1999 Tehran: (Your)((Term)((Project))) 2 | // POJ 1690 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | char s[300]; 9 | 10 | string solve(int &pos){ 11 | string ans = ""; 12 | char before = 0; 13 | while (!(s[pos] == ')' || s[pos] == 0)){ 14 | if (s[pos] == '('){ 15 | pos++; 16 | string tmp = solve(pos); 17 | if (before == '+' || before == 0 || tmp.length() == 1) 18 | ans += tmp; 19 | else 20 | ans += "(" + tmp + ")"; 21 | } 22 | else if (s[pos] != ' '){ 23 | ans += s[pos]; 24 | before = s[pos]; 25 | } 26 | pos++; 27 | } 28 | return ans; 29 | } 30 | 31 | int main(){ 32 | int T; 33 | scanf("%d\n", &T); 34 | while (T--){ 35 | int pos = 0; 36 | gets(s); 37 | printf("%s\n", solve(pos).c_str()); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ICPC.Regional/1999.Tehran/poj1692.cpp: -------------------------------------------------------------------------------- 1 | // 1999 Tehran: Crossed Matchings 2 | // POJ 1692 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 101 9 | 10 | int s1[N], s2[N], match[N][N]; 11 | 12 | int main() { 13 | int T, n1, n2, i, j, k1, k2; 14 | scanf("%d", &T); 15 | while (T--) { 16 | scanf("%d%d", &n1, &n2); 17 | memset(match, 0, sizeof(match)); 18 | for (i = 1; i <= n1; i++) 19 | scanf("%d", &s1[i]); 20 | for (i = 1; i <= n2; i++) 21 | scanf("%d", &s2[i]); 22 | for (i = 1; i <= n1; i++) 23 | for (j = 1; j <= n2; j++) { 24 | match[i][j] = max(match[i][j - 1], match[i - 1][j]); 25 | if (s1[i] == s2[j]) 26 | continue; 27 | for (k1 = i - 1; k1 >= 1; k1--) 28 | if (s1[k1] == s2[j]) 29 | for (k2 = j - 1; k2 >= 1; k2--) 30 | if (s1[i] == s2[k2]) { 31 | match[i][j] = max(match[i][j], match[k1 - 1][k2 - 1] + 2); 32 | break; 33 | } 34 | } 35 | 36 | printf("%d\n", match[n1][n2]); 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ICPC.Regional/1999.Tehran/poj1693.cpp: -------------------------------------------------------------------------------- 1 | // 1999 Tehran: Counting Rectangles 2 | // POJ 1693 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | const int N = 100 + 5; 10 | 11 | struct POINT{ 12 | int x, y; 13 | }; 14 | POINT points[N][2]; 15 | 16 | int solve(){ 17 | int n, ans = 0; 18 | scanf("%d", &n); 19 | for (int i = 0; i < n; i++){ 20 | scanf("%d%d%d%d", &points[i][0].x, &points[i][0].y, &points[i][1].x, &points[i][1].y); 21 | if (points[i][0].x > points[i][1].x) swap(points[i][0].x, points[i][1].x); 22 | if (points[i][0].y > points[i][1].y) swap(points[i][0].y, points[i][1].y); 23 | } 24 | 25 | for (int i = 0; i < n; i++){ 26 | for (int j = i + 1; j < n; j++){ 27 | if (points[i][0].x == points[i][1].x && points[j][0].x == points[j][1].x){ 28 | int cnt = 0, minx = min(points[i][0].x, points[j][0].x), maxx = max(points[i][0].x, points[j][0].x); 29 | for (int k = 0; k < n; k++){ 30 | if (points[k][0].y == points[k][1].y && 31 | points[i][0].y <= points[k][0].y && points[k][0].y <= points[i][1].y && 32 | points[j][0].y <= points[k][0].y && points[k][0].y <= points[j][1].y && 33 | points[k][0].x <= minx && maxx <= points[k][1].x) 34 | cnt++; 35 | } 36 | ans += (cnt - 1) * cnt / 2; 37 | } 38 | } 39 | } 40 | return ans; 41 | } 42 | int main(){ 43 | int T; 44 | scanf("%d", &T); 45 | while (T--) 46 | printf("%d\n", solve()); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /ICPC.Regional/1999.Tehran/poj1695.cpp: -------------------------------------------------------------------------------- 1 | // 1999 Tehran: Magazine Delivery 2 | // POJ 1695 3 | 4 | #include 5 | #include 6 | 7 | const int MAX = 1 << 20; 8 | const int N = 32; 9 | 10 | int d[N][N], f[N][N][N], n; 11 | 12 | void dp() { 13 | memset(f, 127, sizeof(f)); 14 | f[1][1][1] = 0; 15 | for (int k = 2; k <= n; k++) 16 | for (int i = 1; i < k; i++) 17 | for (int j = 1; j < k; j++) { 18 | if (f[i][j][k - 1] + d[i][k] < f[j][k - 1][k]) 19 | f[j][k - 1][k] = f[i][j][k - 1] + d[i][k]; 20 | if (f[i][j][k - 1] + d[j][k] < f[i][k - 1][k]) 21 | f[i][k - 1][k] = f[i][j][k - 1] + d[j][k]; 22 | if (f[i][j][k - 1] + d[k - 1][k] < f[i][j][k]) 23 | f[i][j][k] = f[i][j][k - 1] + d[k - 1][k]; 24 | } 25 | 26 | int ans = f[1][1][n]; 27 | for (int i = 1; i < n; i++) 28 | for (int j = 1; j < n; j++) 29 | if (f[i][j][n] < ans) 30 | ans = f[i][j][n]; 31 | printf("%d\n", ans); 32 | } 33 | 34 | int main() { 35 | int T, i, j; 36 | scanf("%d", &T); 37 | while (T--) { 38 | memset(d, 0, sizeof(d)); 39 | scanf("%d", &n); 40 | for (i = 1; i < n; i++) 41 | for (j = i + 1; j <= n; j++) { 42 | scanf("%d", &d[i][j]); 43 | d[j][i] = d[i][j]; 44 | } 45 | dp(); 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /ICPC.Regional/2000.Tehran/la2052.cpp: -------------------------------------------------------------------------------- 1 | // 2000 Tehran: Number Steps 2 | // ACM-ICPC Live Archive 2052 3 | // POJ 1663 4 | #include 5 | 6 | int x1[5100], x2[5100]; 7 | 8 | void solve() { 9 | int x, y; 10 | scanf("%d %d", &x, &y); 11 | if (x != y && x - y != 2) { 12 | printf("No Number\n"); 13 | return; 14 | } 15 | if (x == y) 16 | printf("%d\n", x1[x]); 17 | else 18 | printf("%d\n", x2[x]); 19 | } 20 | 21 | 22 | int main() { 23 | int T; 24 | 25 | x1[0] = 0; 26 | x1[1] = 1; 27 | x2[2] = 2; 28 | x2[3] = 3; 29 | for (int i = 2; i <= 5001; i++) { 30 | x1[i] = x1[i - 2] + 4; 31 | x2[i + 2] = x2[i] + 4; 32 | } 33 | scanf("%d", &T); 34 | while (T--) 35 | solve(); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /ICPC.Regional/2000.Tehran/la2057.cpp: -------------------------------------------------------------------------------- 1 | // 2000 Tehran: Buggy Sat 2 | // ACM-ICPC Live Archive 2057 3 | // POJ 1687 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | #define N 100 11 | 12 | struct POINT { 13 | double x, y; 14 | POINT(double x, double y) : 15 | x(x), y(y) { 16 | } 17 | 18 | POINT() : 19 | x(0), y(0) { 20 | } 21 | }; 22 | 23 | struct POLY { 24 | int n; 25 | double area; 26 | POINT data[2000]; 27 | }; 28 | 29 | double poly_area(POLY &p) { 30 | double s = p.data[0].y * (p.data[p.n - 1].x - p.data[1].x); 31 | for (int i = 1; i < p.n; i++) 32 | s += p.data[i].y * (p.data[i - 1].x - p.data[(i + 1) % p.n].x); 33 | p.area = s / 2; 34 | return s / 2; 35 | } 36 | 37 | POINT plist[N]; 38 | 39 | int main() { 40 | int T, n, i, j; 41 | scanf("%d", &T); 42 | while (T--) { 43 | POLY polygon; 44 | double maxarea = -1; 45 | int maxid; 46 | scanf("%d", &n); 47 | for (i = 0; i < n; i++) 48 | scanf("%lf%lf", &plist[i].x, &plist[i].y); 49 | scanf("%d", &n); 50 | for (i = 0; i < n; i++) { 51 | scanf("%d", &polygon.n); 52 | for (j = 0; j < polygon.n; j++) { 53 | int id; 54 | scanf("%d", &id); 55 | polygon.data[j] = plist[id - 1]; 56 | } 57 | double ta = fabs(poly_area(polygon)); 58 | 59 | if (ta > maxarea) { 60 | maxarea = ta; 61 | maxid = i; 62 | } 63 | } 64 | printf("%d\n", maxid + 1); 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /ICPC.Regional/2001.Taejon/la2321.cpp: -------------------------------------------------------------------------------- 1 | // 2001 Taejon: Calendar Game 2 | // ACM-ICPC Live Archive 2321 3 | // POJ 1082 4 | 5 | #include 6 | 7 | int main(){ 8 | int T, y, m, d; 9 | scanf("%d", &T); 10 | while (T--){ 11 | scanf("%d%d%d", &y, &m, &d); 12 | if (m == 9 && d == 30 || m == 11 && d == 30) 13 | puts("YES"); 14 | else 15 | puts(m % 2 == d % 2 ? "YES" : "NO"); 16 | } 17 | return 0; 18 | } -------------------------------------------------------------------------------- /ICPC.Regional/2001.Taejon/la2322.cpp: -------------------------------------------------------------------------------- 1 | // 2001 Taejon: Wooden Sticks 2 | // ACM-ICPC Live Archive 2322 3 | // POJ 1065 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | const int N = 5005; 12 | pair stick[N]; 13 | bool used[N]; 14 | 15 | int main(){ 16 | int T, n; 17 | scanf("%d", &T); 18 | while (T--){ 19 | scanf("%d", &n); 20 | for (int i = 0; i < n; i++) 21 | scanf("%d%d", &stick[i].first, &stick[i].second); 22 | sort(stick, stick + n); 23 | 24 | int ans = 0, left = n; 25 | memset(used, 0, sizeof(used)); 26 | while (left > 0){ 27 | int i = 0; 28 | for (i = 0; used[i]; i++); 29 | ans++; 30 | pair last = stick[i]; 31 | for (int j = i; j < n; j++){ 32 | if (!used[j] && last.second <= stick[j].second){ 33 | last = stick[j]; 34 | used[j] = true; 35 | left--; 36 | } 37 | } 38 | } 39 | printf("%d\n", ans); 40 | } 41 | } -------------------------------------------------------------------------------- /ICPC.Regional/2001.Taejon/la2323.cpp: -------------------------------------------------------------------------------- 1 | // 2001 Taejon: Modular Multiplication of Polynomials 2 | // ACM-ICPC Live Archive 2323 3 | // POJ 1060 4 | 5 | #include 6 | #include 7 | 8 | const int N = 2005; 9 | int f[N], g[N], h[N], product[N], remain[N]; 10 | int df, dg, dh; 11 | 12 | void input(int °, int poly[]){ 13 | scanf("%d", °); 14 | for (int i = deg - 1; i >= 0; i--) 15 | scanf("%d", &poly[i]); 16 | } 17 | int main() { 18 | int T; 19 | scanf("%d", &T); 20 | while (T--) { 21 | input(df, f), input(dg, g), input(dh, h); 22 | memset(product, 0, sizeof(product)); 23 | for (int i = 0; i < df; i++) 24 | for (int j = 0; j < dg; j++) 25 | product[i + j] ^= f[i] & g[j]; 26 | 27 | int dp = df + dg, i, j; 28 | while (1){ 29 | while (!product[--dp]); 30 | if (dp + 1 < dh) break; 31 | for (i = dh - 1, j = dp; i >= 0; i--, j--) 32 | product[j] ^= h[i]; 33 | } 34 | printf("%d", dp + 1); 35 | for (int i = dp; i >= 0; i--) 36 | printf(" %d", product[i]); 37 | printf("\n"); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ICPC.Regional/2001.Taejon/la2325.cpp: -------------------------------------------------------------------------------- 1 | // 2001 Taejon: Flip and Shift 2 | // ACM-ICPC Live Archive 2325 3 | // POJ 1063 4 | 5 | #include 6 | 7 | int main(){ 8 | int T, n, c1, c2, x; 9 | scanf("%d", &T); 10 | while (T--){ 11 | scanf("%d", &n); 12 | c1 = c2 = 0; 13 | for (int i = 0; i < n; i++){ 14 | scanf("%d", &x); 15 | i % 2 == 0 ? c1 += x : c2 += x; 16 | } 17 | printf(n % 2 || c1 - c2 == 1 || c2 - c1 == 1 || c1 == c2 ? "YES\n" : "NO\n"); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ICPC.Regional/2001.Taejon/la2326.cpp: -------------------------------------------------------------------------------- 1 | // 2001 Taejon: Moving Tables 2 | // ACM-ICPC Live Archive 2326 3 | // POJ 1083 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | struct WORK{ 11 | int a, b, used; 12 | }; 13 | 14 | int compare(const void* a, const void *b){ 15 | if ((*(WORK *)a).a == (*(WORK *)b).a) 16 | return (*(WORK *)a).b > (*(WORK *)b).b ? 1 : -1; 17 | return (*(WORK *)a).a > (*(WORK *)b).a ? 1 : -1; 18 | } 19 | 20 | int main(){ 21 | int T; 22 | WORK queue[210]; 23 | scanf("%d", &T); 24 | while (T--) { 25 | int i, j, n, time = 0; 26 | scanf("%d", &n); 27 | 28 | for (i = 0; i < n; i++) { 29 | scanf("%d%d", &queue[i].a, &queue[i].b); 30 | if (queue[i].a > queue[i].b) 31 | swap(queue[i].a, queue[i].b); 32 | queue[i].used = 0; 33 | } 34 | 35 | qsort(queue, n, sizeof(queue[0]), compare); 36 | // Check the task one by one. 37 | for (i = 0; i < n; i++) { 38 | if (!queue[i].used) { 39 | queue[i].used = 1; 40 | int u = i; 41 | // Find another moving task 42 | for (j = i + 1; j < n; j++) { 43 | if (!queue[j].used) { 44 | if ((queue[j].a > queue[u].b + 1) || (queue[j].a - 1 == queue[u].b) && (queue[u].b % 2 == 0)) { 45 | queue[j].used = 1; 46 | u = j; 47 | } 48 | } 49 | } 50 | time++; 51 | } 52 | } 53 | printf("%d\n", time * 10); 54 | } 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /ICPC.Regional/2001.Tehran/la2338.cpp: -------------------------------------------------------------------------------- 1 | // 2001 Tehran: Parencodings 2 | // ACM-ICPC Live Archive 2338 3 | // POJ 1068 4 | 5 | #include 6 | #define MAX 30 7 | int arr[MAX], n, T; 8 | 9 | void solve(){ 10 | int num; 11 | printf("1"); 12 | if (n == 1) 13 | return; 14 | for (int i = 1; i <= n; i++) 15 | arr[i]--; 16 | for (int i = 2; i <= n; i++){ 17 | int pos, num = 1; 18 | for (pos = i; pos > 1; pos--){ 19 | if (arr[pos] == arr[pos - 1]) 20 | num++; 21 | else 22 | break; 23 | } 24 | for (int j = pos; j <= n; j++) 25 | arr[j]--; 26 | printf(" %d", num); 27 | } 28 | printf("\n"); 29 | } 30 | 31 | int main(){ 32 | scanf("%d", &T); 33 | while (T--){ 34 | scanf("%d", &n); 35 | for (int i = 1; i <= n; i++) 36 | scanf("%d", &arr[i]); 37 | solve(); 38 | } 39 | return 0; 40 | } -------------------------------------------------------------------------------- /ICPC.Regional/2002.Kaohsiung/poj1339.cpp: -------------------------------------------------------------------------------- 1 | // 2002 Kaohsiung: Poker Card Game 2 | // POJ 1339 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main(){ 9 | int T, n, x, ans; 10 | scanf("%d", &T); 11 | while (T--){ 12 | priority_queue q; 13 | ans = 0; 14 | scanf("%d", &n); 15 | for (int i = 0; i < n; i++){ 16 | scanf("%d", &x); 17 | q.push(-x); 18 | } 19 | 20 | while (q.size() > 1){ 21 | int a = q.top(); 22 | q.pop(); 23 | int b = q.top(); 24 | q.pop(); 25 | 26 | q.push(a + b); 27 | ans += a + b; 28 | } 29 | 30 | printf("%d\n", -ans); 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ICPC.Regional/2002.Kaohsiung/poj1344.cpp: -------------------------------------------------------------------------------- 1 | // 2002 Kaohsiung: Tree Size Problem 2 | // POJ 1344 3 | #include 4 | #include 5 | #define N 50 6 | int n, D[N][N], vis[N]; 7 | void solve() { 8 | int ans = 0; 9 | memset(vis, 0, sizeof(vis)); 10 | for (int i = 0; i < n - 1; i++) 11 | for (int j = i + 1; j < n; j++) 12 | scanf("%d", &D[i][j]); 13 | 14 | for (int round = 0; round < n - 2; round++) { 15 | int minDis = 1<<30, next; 16 | for (int i = 0; i < n; i++) 17 | for (int j = i + 1; j < n; j++) 18 | for (int k = j + 1; k < n; k++) 19 | if (!vis[i] && !vis[j] && !vis[k]) { 20 | int dis = (D[i][j] + D[i][k] - D[j][k]) / 2; 21 | if (dis < minDis) { 22 | next = i; 23 | minDis = dis; 24 | } 25 | } 26 | ans += minDis; 27 | vis[next] = 1; 28 | } 29 | 30 | int a = -1, b = -1; 31 | for (int i = 0; i < n; i++) { 32 | if (!vis[i]) 33 | (a == -1) ? (a = i) : (b = i); 34 | } 35 | ans += D[a][b]; 36 | printf("%d\n", ans); 37 | } 38 | int main() { 39 | while (scanf("%d", &n) && n) 40 | solve(); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /ICPC.Regional/2003.Guangzhou/la2948.cpp: -------------------------------------------------------------------------------- 1 | // 2003 Guangzhou: Special Experiment 2 | // ACM-ICPC Live Archive 2948 3 | // POJ 1770 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define N 205 10 | int n, m; 11 | int st[N], ph[N], dp[N][2]; 12 | vector G[N]; 13 | bool v[N]; 14 | //dp 0: not used; dp 1: used 15 | void dfs(int x) 16 | { 17 | int i, y; 18 | v[x] = 1; 19 | dp[x][0] = 0, dp[x][1] = st[x]; 20 | for(i = 0; i < (int)G[x].size(); i++) 21 | { 22 | y = G[x][i]; 23 | if(!v[y]) 24 | { 25 | dfs(y); 26 | dp[x][0] += max(dp[y][0], dp[y][1]); 27 | dp[x][1] += dp[y][0]; 28 | } 29 | } 30 | } 31 | int solve() { 32 | int i, j; 33 | for (i = 0; i < n; i++) 34 | { 35 | G[i].clear(); 36 | scanf("%d", &st[i]); 37 | } 38 | for (i = 0; i < m; i++) 39 | scanf("%d", &ph[i]); 40 | 41 | sort(ph, ph + m); 42 | for(i = 0; i < n; i++) 43 | for(j = i+1; j < n; j++) 44 | { 45 | if(binary_search(ph, ph+m, st[j] - st[i])) 46 | G[i].push_back(j), G[j].push_back(i); 47 | } 48 | memset(v, 0, sizeof(v)); 49 | dfs(0); 50 | return max(dp[0][0], dp[0][1]); 51 | } 52 | int main() { 53 | while (scanf("%d%d", &n, &m) && n) 54 | printf("%d\n", solve()); 55 | return 0; 56 | } -------------------------------------------------------------------------------- /ICPC.Regional/2003.Guangzhou/la2953.cpp: -------------------------------------------------------------------------------- 1 | // 2003 Guangzhou: Sum of Factorials 2 | // ACM-ICPC Live Archive 2953 3 | // POJ 1775 4 | #include 5 | #include 6 | #define N 30 7 | int a[N] = { 1, 1 }; 8 | int main() { 9 | int i, n; 10 | for (i = 2; i <= 12; i++) 11 | a[i] = a[i - 1] * i; 12 | 13 | while (scanf("%d", &n) && n >= 0) { 14 | if (n == 0) { 15 | puts("NO"); 16 | continue; 17 | } 18 | i = 12; 19 | while (n >= 0 && i >= 0) { 20 | if (n >= a[i]) n -= a[i]; 21 | i--; 22 | } 23 | if (n == 0) puts("YES"); 24 | else puts("NO"); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ICPC.Regional/2003.Guangzhou/la2954.cpp: -------------------------------------------------------------------------------- 1 | // 2003 Guangzhou: Task Sequences 2 | // ACM-ICPC Live Archive 2954 3 | // POJ 1776 4 | #include 5 | #include 6 | #define N 1005 7 | int g[N][N], path[N], n; 8 | 9 | void find() { 10 | int i, j, k; 11 | for (i = 1; i <= n; i++) { 12 | j = 0; 13 | while (1) { 14 | k = path[j]; 15 | if (k == -1) { 16 | path[j] = i; 17 | break; 18 | } 19 | if (g[i][k]) { 20 | path[j] = i, path[i] = k; 21 | break; 22 | } 23 | j = k; 24 | } 25 | } 26 | } 27 | char cmd[10000]; 28 | void read() { 29 | int i, j, k; 30 | getchar(); 31 | for (i = 1; i <= n; i++) { 32 | k = 0, j = 1; 33 | gets(cmd); 34 | while (cmd[k]) { 35 | if (cmd[k] == '1') g[i][j++] = 1; 36 | if (cmd[k] == '0') g[i][j++] = 0; 37 | k++; 38 | } 39 | } 40 | } 41 | void solve() { 42 | int i; 43 | read(); 44 | memset(path, -1, sizeof(path)); 45 | find(); 46 | i = 0; 47 | while (1) { 48 | printf("%d ", path[i]); 49 | i = path[i]; 50 | if (path[i] == -1) break; 51 | } 52 | printf("\n"); 53 | } 54 | int main() { 55 | while (scanf("%d", &n) != EOF) { 56 | printf("1\n%d\n", n); 57 | solve(); 58 | } 59 | return 0; 60 | } -------------------------------------------------------------------------------- /ICPC.Regional/2004.Shanghai/la3266.cpp: -------------------------------------------------------------------------------- 1 | // 2004 Shanghai: Tian Ji -- The Horse Racing 2 | // ACM-ICPC Live Archive 3266 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | const int N = 1005; 9 | int horse[2][N], n; 10 | 11 | int main(){ 12 | while (scanf("%d", &n) && n){ 13 | for (int i = 0; i < 2; i++){ 14 | for (int j = 0; j < n; j++) 15 | scanf("%d", &horse[i][j]); 16 | sort(horse[i], horse[i] + n); 17 | } 18 | 19 | int ans = 0, b0 = 0, b1 = 0, e0 = n - 1, e1 = n - 1; 20 | while (b0 <= e0){ 21 | if (horse[0][e0] > horse[1][e1]) 22 | e0--, e1--, ans++; 23 | else if (horse[0][e0] < horse[1][e1]) 24 | b0++, e1--, ans--; 25 | else{ 26 | if (horse[0][b0] > horse[1][b1]) 27 | b0++, b1++, ans++; 28 | else{ 29 | if (horse[0][b0] < horse[1][e1]) 30 | ans--; 31 | b0++, e1--; 32 | } 33 | } 34 | } 35 | printf("%d\n", ans * 200); 36 | } 37 | return 0; 38 | } -------------------------------------------------------------------------------- /ICPC.Regional/2005.Central_Europe/3527.cpp: -------------------------------------------------------------------------------- 1 | // CII 3527 2 | // 2005 Central Europe: Find the Clones 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 20005 8 | typedef long long ll; 9 | 10 | int n, m; 11 | int map[100]; 12 | short ans[N]; 13 | ll num[N]; 14 | void get(int x) { 15 | num[x] = 0; 16 | for (int i = 0; i < m; i++) { 17 | char ch = getchar(); 18 | num[x] = (num[x] << 2) | map[(int) ch]; 19 | } 20 | getchar(); 21 | } 22 | int main() { 23 | map['A'] = 0, map['T'] = 1, map['C'] = 2, map['G'] = 3; 24 | while (scanf("%d%d\n", &n, &m) && n + m) { 25 | int i, dup; 26 | memset(ans, 0, sizeof(ans)); 27 | for (i = 0; i < n; i++) 28 | get(i); 29 | sort(num, num + n); 30 | dup = 1; 31 | for (i = 1; i < n; i++) { 32 | if (num[i] == num[i - 1]) dup++; 33 | else { 34 | ans[dup]++; 35 | dup = 1; 36 | } 37 | } 38 | ans[dup]++; 39 | for (i = 1; i <= n; i++) 40 | printf("%d\n", ans[i]); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /ICPC.Regional/2005.Rocky_Mountain/la3337.cpp: -------------------------------------------------------------------------------- 1 | // Rocky Mountain 2005: Random Walk 2 | // ACM-ICPC Live Archive 3337 3 | // POJ 2714 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define N 205 10 | int n; 11 | 12 | struct POINT { 13 | double x, y, a; 14 | double len2() { 15 | return x * x + y * y; 16 | } 17 | void get() { 18 | scanf("%lf%lf", &x, &y); 19 | } 20 | bool operator<(const POINT &p) const { 21 | return a < p.a; 22 | } 23 | POINT operator +(const POINT &p) { 24 | POINT ret; 25 | ret.x = x + p.x, ret.y = y + p.y; 26 | return ret; 27 | } 28 | }; 29 | 30 | POINT pl[N]; 31 | double solve() { 32 | double ans = 0, t; 33 | int i, j; 34 | for (i = 0; i < 2 * n;) { 35 | pl[i].get(); 36 | pl[i].a = atan2(pl[i].y, pl[i].x); 37 | i++; 38 | pl[i].x = -pl[i - 1].x, pl[i].y = -pl[i - 1].y; 39 | pl[i].a = atan2(pl[i].y, pl[i].x); 40 | i++; 41 | } 42 | sort(pl, pl + 2 * n); 43 | for (i = 0; i < 2 * n; i++) { 44 | POINT v; 45 | v.x = v.y = 0; 46 | for (j = 0; j < n; j++) { 47 | v = v + pl[(i + j) % (2 * n)]; 48 | } 49 | t = v.len2(); 50 | ans = t > ans ? t : ans; 51 | } 52 | return sqrt(ans); 53 | } 54 | int main() { 55 | while (scanf("%d", &n) && n) 56 | printf("Maximum distance = %.3lf meters.\n", solve()); 57 | } -------------------------------------------------------------------------------- /ICPC.Regional/2005.Rocky_Mountain/la3342.cpp: -------------------------------------------------------------------------------- 1 | // Rocky Mountain 2005: Faulty Odometer 2 | // ACM-ICPC Live Archive 3342 3 | // POJ 2719 4 | 5 | #include 6 | #include 7 | 8 | int nine[11] = { 1 }; 9 | int main() { 10 | char s[20], ch; 11 | int i, sum, j; 12 | for (i = 1; i <= 10; i++) 13 | nine[i] = nine[i - 1] * 9; 14 | while (scanf("%s", s) && s[0] - '0') { 15 | sum = j = 0; 16 | for (i = strlen(s) - 1; i >= 0; i--, j++) { 17 | if ((ch = s[i]) > '4') 18 | ch--; 19 | sum += nine[j] * (ch - '0'); 20 | } 21 | printf("%s: %d\n", s, sum); 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ICPC.Regional/2005.Rocky_Mountain/la3344.cpp: -------------------------------------------------------------------------------- 1 | // Rocky Mountain 2005: Suit Distribution 2 | // ACM-ICPC Live Archive 3344 3 | // POJ 2721 4 | 5 | #include 6 | #include 7 | #include 8 | double solve(int a, int b) 9 | { 10 | double ans = 1.0; 11 | int mo[28], i; 12 | memset(mo, 0, sizeof(mo)); 13 | for(i = 2; i <= 13; i++) 14 | mo[i] = 1; 15 | for(i = 14; i<= 26; i++) 16 | mo[i] = -1; 17 | for(i = 2; i <= a+b; i++) 18 | mo[i]++; 19 | for(i = 2; i <= a; i++) 20 | mo[i]--; 21 | for(i = 2; i <= b; i++) 22 | mo[i]--; 23 | for(i = 2; i <= 26-a-b; i++) 24 | mo[i]++; 25 | for(i = 2; i <= 13-a; i++) 26 | mo[i]--; 27 | for(i = 2; i <= 26-a-b-(13-a); i++) 28 | mo[i]--; 29 | 30 | for(i = 2;i <= 26; i++) 31 | { 32 | while(mo[i] < 0) 33 | { 34 | ans /= (double)i; 35 | mo[i]++; 36 | } 37 | while(mo[i] > 0) 38 | { 39 | ans *= (double)i; 40 | mo[i]--; 41 | } 42 | } 43 | if(a != b) 44 | ans *= 2; 45 | return ans; 46 | } 47 | 48 | int main() 49 | { 50 | int a, b; 51 | while(scanf("%d%d", &a, &b) && a != -1) 52 | { 53 | printf("%d-%d split: %.8lf\n",a,b, solve(a, b)); 54 | } 55 | return 0; 56 | } -------------------------------------------------------------------------------- /ICPC.Regional/2005.Southwestern_Europe/la3502.cpp: -------------------------------------------------------------------------------- 1 | // 2005 Southwestern Europe: The mysterious X network 2 | // ACM-ICPC Live Archive 3502 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define N 100005 8 | using namespace std; 9 | int n, s, t; 10 | vector G[N]; 11 | 12 | int v[N]; 13 | int bfs() { 14 | queue Q; 15 | int pt, dep = 0, size = 1, ts; 16 | v[s] = 0; 17 | Q.push(s); 18 | while (!Q.empty()) { 19 | ts = 0; 20 | while (size--) { 21 | pt = Q.front(); 22 | Q.pop(); 23 | if (pt == t) return v[t]; 24 | for (size_t i = 0; i < G[pt].size(); i++) { 25 | int x; 26 | x = G[pt][i]; 27 | if (v[x] == -1) { 28 | v[x] = dep; 29 | Q.push(x); 30 | ts++; 31 | } 32 | } 33 | } 34 | size = ts; 35 | dep++; 36 | } 37 | return 0; 38 | } 39 | int main() { 40 | int T, ca, j, c, k; 41 | scanf("%d", &T); 42 | for (int ca = 0; ca < T; ca++){ 43 | if (ca) printf("\n"); 44 | scanf("%d", &n); 45 | for (int i = 0; i < n; i++) 46 | G[i].clear(); 47 | 48 | for (int i = 0; i < n; i++) { 49 | scanf("%d%d", &c, &k); 50 | for (j = 0; j < k; j++) { 51 | int x; 52 | scanf("%d", &x); 53 | G[c].push_back(x); 54 | G[x].push_back(c); 55 | } 56 | } 57 | scanf("%d%d", &s, &t); 58 | memset(v, -1, sizeof(v)); 59 | printf("%d %d %d\n", s, t, bfs()); 60 | } 61 | return 0; 62 | } -------------------------------------------------------------------------------- /ICPC.Regional/2005.Southwestern_Europe/la3506.cpp: -------------------------------------------------------------------------------- 1 | // 2005 Southwestern Europe: 4 Values whose Sum is 0 2 | // ACM-ICPC Live Archive 3506 3 | #include 4 | #include 5 | #define M 4005 6 | #define SIZE 4000037 7 | using namespace std; 8 | int a[M][4]; 9 | int value[SIZE], amount[SIZE], use[SIZE]; 10 | int locate(int s) { 11 | int h; 12 | h = s; 13 | while (h < 0) 14 | h += SIZE; 15 | while (h >= SIZE) 16 | h -= SIZE; 17 | while (use[h] && value[h] != s) { 18 | h++; 19 | if (h >= SIZE) 20 | h -= SIZE; 21 | } 22 | return h; 23 | } 24 | void insert(int s) { 25 | int posi = locate(s); 26 | if (!use[posi]) { 27 | use[posi] = 1; 28 | value[posi] = s; 29 | } 30 | amount[posi]++; 31 | } 32 | 33 | int main() { 34 | int n, i, j, x, T; 35 | scanf("%d", &T); 36 | for (int ca = 0; ca < T; ca++) { 37 | if (ca) 38 | printf("\n"); 39 | long long ans = 0; 40 | memset(use, 0, sizeof(use)); 41 | memset(amount, 0, sizeof(amount)); 42 | scanf("%d", &n); 43 | for (i = 0; i < n; i++) 44 | for (j = 0; j < 4; j++) 45 | scanf("%d", &a[i][j]); 46 | for (i = 0; i < n; i++) { 47 | for (j = 0; j < n; j++) { 48 | x = a[i][0] + a[j][1]; 49 | insert(x); 50 | } 51 | } 52 | for (i = 0; i < n; i++) { 53 | for (j = 0; j < n; j++) { 54 | x = a[i][2] + a[j][3]; 55 | int posi = locate(-x); 56 | if (value[posi] == -x) 57 | ans += amount[posi]; 58 | } 59 | } 60 | printf("%lld\n", ans); 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /ICPC.Regional/2005.Southwestern_Europe/la3507.cpp: -------------------------------------------------------------------------------- 1 | // 2005 Southwestern Europe: Keep the Customer Satisfied 2 | // ACM-ICPC Live Archive 3507 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 800005 9 | 10 | int n, l; 11 | struct NODE { 12 | int q, d; 13 | bool operator <(const NODE &x) const { 14 | return d < x.d; 15 | } 16 | }; 17 | NODE nl[N]; 18 | 19 | int main() { 20 | int T; 21 | scanf("%d", &T); 22 | for (int ca = 0; ca < T; ca++){ 23 | if (ca) 24 | printf("\n"); 25 | priority_queue, less::value_type> > Q; 26 | scanf("%d", &n); 27 | int i, c = 0; 28 | for (i = 0; i < n; i++) 29 | scanf("%d%d", &nl[i].q, &nl[i].d); 30 | sort(nl, nl + n); 31 | for (i = 0; i < n; i++) { 32 | Q.push(nl[i].q); 33 | c += nl[i].q; 34 | if (c > nl[i].d) { 35 | c -= Q.top(); 36 | Q.pop(); 37 | } 38 | } 39 | printf("%d\n", Q.size()); 40 | } 41 | return 0; 42 | } -------------------------------------------------------------------------------- /ICPC.Regional/2005.Southwestern_Europe/la3511.cpp: -------------------------------------------------------------------------------- 1 | // 2005 Southwestern Europe: Consecutive ones 2 | // ACM-ICPC Live Archive 3511 3 | #include 4 | #include 5 | #define N 405 6 | bool map[N][N], use[N]; 7 | int cnt[N], ans[N], n, m; 8 | void init() { 9 | int i, j; 10 | char cmd[500]; 11 | scanf("%d\n%d\n", &n, &m); 12 | memset(cnt, 0, sizeof(cnt)); 13 | memset(use, 0, sizeof(use)); 14 | for (i = 0; i < n; i++) { 15 | scanf("%s", cmd); 16 | for (j = 0; j < m; j++) { 17 | bool p = cmd[j] == '1'; 18 | map[i][j] = p; 19 | if (j) cnt[i] += p; 20 | } 21 | } 22 | ans[0] = 0; 23 | } 24 | int dfs(int x) { 25 | int i, j, ok; 26 | if (x == m) return 1; 27 | for (i = 1; i < m; i++) { 28 | if (use[i]) continue; 29 | for (j = 0, ok = 1; j < n && ok; j++) 30 | if (cnt[j] && !map[j][i] && map[j][ans[x - 1]]) ok = 0; 31 | if (!ok) continue; 32 | use[i] = 1, ans[x] = i; 33 | for (j = 0; j < n; j++) 34 | cnt[j] -= map[j][i]; 35 | if (dfs(x + 1)) return 1; 36 | use[i] = 0; 37 | for (j = 0; j < n; j++) 38 | cnt[j] += map[j][i]; 39 | } 40 | return 0; 41 | } 42 | 43 | int main() { 44 | int T; 45 | scanf("%d", &T); 46 | for (int ca = 0; ca < T; ca++){ 47 | if (ca) printf("\n"); 48 | init(); 49 | dfs(1); 50 | for (int i = 0; i < m; i++) 51 | printf("%d\n", ans[i]); 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /ICPC.Regional/2005.Tokyo/3404.cpp: -------------------------------------------------------------------------------- 1 | // 2005 Tokyo: Atomic Car Race 2 | // CII 3404 3 | #include 4 | #include 5 | using namespace std; 6 | #define N 10005 7 | double v, e, f, b; 8 | int dis[N]; 9 | double opt[N],need_time[N]; 10 | int r, n; 11 | void calc_time() { 12 | int i; 13 | double t; 14 | need_time[0] = 0; 15 | for (i = 0; i <= dis[n]+1; i++) { 16 | if (i >= r) 17 | t = 1.0 / (v - e * (i - r)); 18 | else 19 | t= 1.0 / (v - f * (r - i)); 20 | need_time[i+1] = need_time[i] + t; 21 | } 22 | } 23 | 24 | int main() { 25 | int i, j; 26 | while (scanf("%d", &n) && n) { 27 | double min, tmp; 28 | dis[0] = 0; 29 | for (i = 1; i <= n; i++) 30 | scanf("%d", &dis[i]); 31 | scanf("%lf", &b); 32 | scanf("%d%lf%lf%lf", &r, &v, &e, &f); 33 | calc_time(); 34 | opt[0] = 0.0; 35 | for (i = 1; i <= n; i++) { 36 | min = 99999999; 37 | for (j = 0; j < i; j++) { 38 | if ((tmp = opt[j] + need_time[dis[i] - dis[j]]) < min) 39 | min = tmp; 40 | } 41 | opt[i] = min + b; 42 | } 43 | printf("%.4lf\n", opt[n] - b); 44 | } 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /ICPC.Regional/2006.Beijing/img/la3661_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Beijing/img/la3661_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Dhaka/la2189.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Dhaka: Potentiometers 2 | // ACM-ICPC Live Archive 2191 3 | #include 4 | #include 5 | 6 | #define N 200005 7 | typedef long long ll; 8 | #define lowbit(x) (x&(x^(x-1))) 9 | ll C[N]; 10 | int n; 11 | void modify(int pos, ll d) { 12 | while (pos <= n) 13 | C[pos] += d, pos += lowbit(pos); 14 | } 15 | ll query(int pos) { 16 | ll sum = 0; 17 | while (pos > 0) 18 | sum += C[pos], pos -= lowbit(pos); 19 | return sum; 20 | } 21 | 22 | ll base[N]; 23 | 24 | int main() { 25 | int i, ca = 1; 26 | while (scanf("%d", &n) && n) { 27 | char cmd[10]; 28 | if (ca != 1) printf("\n"); 29 | printf("Case %d:\n", ca++); 30 | memset(C, 0, sizeof(C)); 31 | for (i = 1; i <= n; i++) { 32 | scanf("%lld", base + i); 33 | modify(i, base[i]); 34 | } 35 | while (scanf("%s", cmd) && cmd[0] != 'E') { 36 | int a, b; 37 | long long x; 38 | if (cmd[0] == 'S') { 39 | scanf("%d%lld", &a, &x); 40 | modify(a, x - base[a]); 41 | base[a] = x; 42 | } else if (cmd[0] == 'M') { 43 | scanf("%d%d", &a, &b); 44 | printf("%lld\n", query(b) - query(a - 1)); 45 | } 46 | } 47 | } 48 | return 0; 49 | } -------------------------------------------------------------------------------- /ICPC.Regional/2006.Dhaka/la2191.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Dhaka: Mobile Casanova 2 | // ACM-ICPC Live Archive 2189 3 | #include 4 | #include 5 | #define N 100005 6 | 7 | typedef long long ll; 8 | char list[N][20]; 9 | ll num[N]; 10 | int main() { 11 | int n, i, j, len, ca = 1; 12 | while (scanf("%d", &n) && n) { 13 | printf("Case %d:\n", ca++); 14 | for (i = 0; i < n; i++) { 15 | scanf("%s", list[i]); 16 | sscanf(list[i], "%lld", &num[i]); 17 | } 18 | len = strlen(list[0]); 19 | int begin = 0, st = 1; 20 | for (i = 1; i < n; i++) { 21 | 22 | if (num[i] - num[i - 1] > 1) { 23 | if (i - begin == 1) { 24 | printf("%s", list[begin]); 25 | } else { 26 | printf("%s-", list[begin]); 27 | for (j = 0; j < len; j++) 28 | if (list[begin][j] != list[i - 1][j]) break; 29 | for (; j < len; j++) 30 | printf("%c", list[i - 1][j]); 31 | } 32 | printf("\n"); 33 | begin = i; 34 | } 35 | } 36 | 37 | if (i - begin == 1) { 38 | printf("%s", list[begin]); 39 | } else { 40 | printf("%s-", list[begin]); 41 | for (j = 0; j < len; j++) 42 | if (list[begin][j] != list[i - 1][j]) break; 43 | for (; j < len; j++) 44 | printf("%c", list[i - 1][j]); 45 | } 46 | printf("\n\n"); 47 | } 48 | return 0; 49 | } -------------------------------------------------------------------------------- /ICPC.Regional/2006.Northeastern_Europe/img/la3702_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Northeastern_Europe/img/la3702_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Northeastern_Europe/img/la3702_img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Northeastern_Europe/img/la3702_img2.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Northeastern_Europe/img/la3710_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Northeastern_Europe/img/la3710_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Northeastern_Europe/la3708.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Northeastern Europe: Graveyard 2 | // ACM-ICPC Live Archive 3708 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #define PI 3.1415926536 10 | struct POINT { 11 | double c; 12 | int f; 13 | POINT() { 14 | } 15 | POINT(double c, int f) : 16 | c(c), f(f) { 17 | } 18 | bool operator<(const POINT &x) const { 19 | return c < x.c; 20 | } 21 | }; 22 | 23 | 24 | int n, m; 25 | double solve() { 26 | double CR, d1, d2; 27 | vector pl; 28 | CR = 10000; 29 | if (n == m) 30 | return 0.0; 31 | 32 | d1 = CR / n; 33 | d2 = CR / (m + n); 34 | for (int i = 1; i < n; i++) 35 | pl.push_back(POINT(d1 * i, 0)); 36 | for (int i = 1; i < m + n; i++) 37 | pl.push_back(POINT(d2 * i, 1)); 38 | sort(pl.begin(), pl.end()); 39 | 40 | double ans = 0; 41 | for (size_t i = 0; i < pl.size(); i++) 42 | if (pl[i].f == 0) { 43 | double up, dn; 44 | up = pl[i + 1].c - pl[i].c; 45 | dn = pl[i].c - pl[i - 1].c; 46 | if (dn < up && pl[i - 1].f == 1) { 47 | ans += dn; 48 | } else { 49 | ans += up; 50 | pl[i + 1].f = 2; 51 | 52 | } 53 | } 54 | 55 | return ans; 56 | } 57 | 58 | int main(){ 59 | while(~scanf("%d%d", &n, &m)) 60 | printf("%.5lf\n", solve()); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /ICPC.Regional/2006.Northeastern_Europe/la3712.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Northeastern Europe: Kickdown 2 | // ACM-ICPC Live Archive 3712 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | const int N = 105; 10 | char s1[N], s2[N]; 11 | 12 | int check(char *s1, char *s2){ 13 | int l1 = strlen(s1), l2 = strlen(s2); 14 | int ans = l1 + l2; 15 | for (int i = 0; i < l1; i++){ 16 | bool ok = true; 17 | for (int j = 0; j < l2 && i + j < l1 && ok; j++){ 18 | if (s1[i + j] == '2' && s2[j] == '2') 19 | ok = false; 20 | } 21 | if (ok){ 22 | int len = max(l1, i + l2); 23 | ans = min(len, ans); 24 | } 25 | } 26 | return ans; 27 | } 28 | int main(){ 29 | while (~scanf("%s%s", s1, s2)) 30 | printf("%d\n", min(check(s1, s2), check(s2, s1))); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/img/la3582_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Rocky_Mountain/img/la3582_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/img/la3582_img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Rocky_Mountain/img/la3582_img2.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/img/la3582_img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Rocky_Mountain/img/la3582_img3.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/img/la3582_img4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Rocky_Mountain/img/la3582_img4.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/img/la3582_img5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Rocky_Mountain/img/la3582_img5.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/la3576.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Rocky Mountain: Baskets of Gold Coins 2 | // ACM-ICPC Live Archive 3576 3 | 4 | #include 5 | long long n, w, d, sum; 6 | int main() { 7 | while (scanf("%lld%lld%lld%lld", &n, &w, &d, &sum) != EOF) { 8 | n -= 1; 9 | long long ss = (n * n + n) / 2, s2; 10 | s2 = ss * w; 11 | if (s2 == sum) printf("%lld\n", n + 1); 12 | else printf("%lld\n", (s2 - sum) / d); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ICPC.Regional/2006.Rocky_Mountain/la3582.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Rocky Mountain: Knots 2 | // ACM-ICPC Live Archive 3582 3 | 4 | #include 5 | double calc(int n) { 6 | double ans = 1; 7 | int i; 8 | for (i = n - 2; i > 1; i -= 2) 9 | ans = (double) i / (double) (i + 1) * ans; 10 | return ans; 11 | } 12 | int main() { 13 | int n; 14 | while (scanf("%d", &n) != EOF) { 15 | printf("%.5lf\n", calc(n)); 16 | } 17 | return 0; 18 | } -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/3616.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Yokohama: How I Wonder What You Are! 2 | // POJ 3129 3 | // ACM-ICPC Live Archive 3616 4 | #include 5 | #include 6 | #define N 1000 7 | 8 | struct POINT { 9 | double x, y, z, a; 10 | double abs() { 11 | return sqrt(x * x + y * y + z * z); 12 | } 13 | }; 14 | 15 | int ns, nt; 16 | POINT stars[N], telescopes[N]; 17 | 18 | int check_visible(int i, int j) { 19 | double v = stars[i].x * telescopes[j].x + stars[i].y * telescopes[j].y + stars[i].z * telescopes[j].z; 20 | v = v / stars[i].abs() / telescopes[j].abs(); 21 | if (v < 0) 22 | return 0; 23 | return acos(v) < telescopes[j].a; 24 | } 25 | 26 | int main() { 27 | while (scanf("%d", &ns) && ns) { 28 | int ans = 0; 29 | for (int i = 0; i < ns; i++) 30 | scanf("%lf%lf%lf", &stars[i].x, &stars[i].y, &stars[i].z); 31 | 32 | scanf("%d", &nt); 33 | for (int i = 0; i < nt; i++) 34 | scanf("%lf%lf%lf%lf", &telescopes[i].x, &telescopes[i].y, &telescopes[i].z, &telescopes[i].a); 35 | 36 | for (int i = 0; i < ns; i++) 37 | for (int j = 0; j < nt; j++) 38 | if (check_visible(i, j)) { 39 | ans++; 40 | break; 41 | } 42 | printf("%d\n", ans); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/3621.cpp: -------------------------------------------------------------------------------- 1 | // 2006 Yokohama: Power Calculus 2 | // ACM-ICPC Live Archive 3621 3 | // POJ 3134 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 1005 9 | #define M 1000 10 | int ans[N]; 11 | struct NODE { 12 | short step, mi, get[15], gz; 13 | bool operator <(const NODE &n) const { 14 | return step > n.step; 15 | } 16 | }; 17 | priority_queue Q; 18 | 19 | void precalc() { 20 | int i; 21 | NODE st; 22 | st.gz = 1, st.get[0] = 1; 23 | st.step = 0, st.mi = 1; 24 | Q.push(st); 25 | for (i = 1; i <= M; i++) 26 | ans[i] = 100000; 27 | while (!Q.empty()) { 28 | NODE top = Q.top(); 29 | Q.pop(); 30 | if (top.step < ans[top.mi]) ans[top.mi] = top.step; 31 | for (i = 0; i < top.gz; i++) { 32 | NODE nst = top; 33 | nst.mi += top.get[i]; 34 | if (nst.mi > M) continue; 35 | nst.step++; 36 | if (nst.step < ans[nst.mi] && nst.gz < 14) { 37 | nst.get[nst.gz++] = nst.mi; 38 | Q.push(nst); 39 | } 40 | } 41 | 42 | for (i = 0; i < top.gz; i++) { 43 | NODE nst = top; 44 | nst.mi -= top.get[i]; 45 | if (nst.mi < 2) continue; 46 | nst.step++; 47 | if (nst.step < ans[nst.mi] && nst.gz < 14) { 48 | nst.get[nst.gz++] = nst.mi; 49 | Q.push(nst); 50 | } 51 | } 52 | } 53 | } 54 | 55 | int main() { 56 | precalc(); 57 | int n; 58 | while (scanf("%d", &n) && n) 59 | printf("%d\n", ans[n]); 60 | return 0; 61 | } -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/img/3618_img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Yokohama/img/3618_img1.png -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/img/3618_img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Yokohama/img/3618_img2.png -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/img/3618_img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Yokohama/img/3618_img3.png -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/img/3618_img4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Yokohama/img/3618_img4.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2006.Yokohama/img/3622_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2006.Yokohama/img/3622_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2007.Beijing/la4032.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Beijing: Jewel Trading 2 | // ACM-ICPC Live Archive 4032 3 | #include 4 | #include 5 | #include 6 | #define EPS 1e-3 7 | double a, b, pre; 8 | int n; 9 | 10 | double F(double x) { 11 | return pre + (x - pre) / (1 + pow((x - a), b)); 12 | } 13 | double trois() { 14 | double l, r, m, mm; 15 | l = pre, r = 1e5; 16 | while (l + EPS < r) { 17 | m = (l + r) / 2; 18 | mm = (m + r) / 2; 19 | double y1 = F(m), y2 = F(mm); 20 | if (y1 >= y2) r = mm; 21 | else l = m; 22 | } 23 | double m1 = F(ceil(m)), m2 = F(floor(m)); 24 | return m1 > m2 ? m1 : m2; 25 | } 26 | 27 | void solve() { 28 | int i; 29 | scanf("%lf%lf", &a, &b); 30 | pre = a; 31 | for (i = 0; i < n - 1; i++) 32 | pre = trois(); 33 | printf("%.2lf\n", pre); 34 | } 35 | int main() { 36 | int T = 1; 37 | while (scanf("%d", &n) && n) { 38 | printf("Case %d: ", T++); 39 | solve(); 40 | } 41 | return 0; 42 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Dhaka/la4055.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Dhaka: Bachelor Arithmetic 2 | // ACM-ICPC Live Archive 4055 3 | #include 4 | #include 5 | int main() { 6 | int B, S, T=1; 7 | while (scanf("%d%d", &B, &S) && B + S) { 8 | printf("Case %d: ", T++); 9 | if (B - 1 == 0) printf(":-\\\n"); 10 | else { 11 | if(B==S || BS) 14 | printf(":-(\n"); 15 | } 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Dhaka/la4056.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Dhaka: Nested Squares 2 | // ACM-ICPC Live Archive 4056 3 | #include 4 | #include 5 | #define N 50005 6 | char s[N]; 7 | int iabs(int x) 8 | { 9 | return x < 0 ? -x : x; 10 | } 11 | void solve() { 12 | int Q, cq = 1, x1, x2, y1, y2, i, j, len; 13 | scanf("%s%d", s, &Q); 14 | len = strlen(s); 15 | while (Q--) { 16 | printf("Query %d:\n", cq++); 17 | scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 18 | for (i = x1; i <= x2; i++) { 19 | for (j = y1; j <= y2; j++) { 20 | int d1 = iabs(i - len), d2 = iabs(j - len); 21 | int d = d1 > d2 ? d1 : d2; 22 | printf("%c", s[len-1-d]); 23 | } 24 | printf("\n"); 25 | } 26 | } 27 | printf("\n"); 28 | } 29 | int main() { 30 | int T, ca = 1; 31 | scanf("%d", &T); 32 | while (T--) { 33 | printf("Square %d:\n", ca++); 34 | solve(); 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Northwestern_Europe/img/la3975_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2007.Northwestern_Europe/img/la3975_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2007.Northwestern_Europe/la3973.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Nouthwestern Europe: Containers 2 | // ACM-ICPC Live Archive 3973 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | const long long INF = 1LL << 60LL; 8 | 9 | long long area(long long n, long long m) 10 | { 11 | long long nn, mm; 12 | nn = max(n, m); 13 | mm = min(n, m); 14 | return (10 * nn + 2) * (44 * mm + 4); 15 | } 16 | 17 | int main() 18 | { 19 | int T; 20 | long long x, n, i, u1, u2; 21 | double dn; 22 | scanf("%d", &T); 23 | while (T--) 24 | { 25 | long long ans = INF, a, b, aa, bb; 26 | 27 | scanf("%lld", &x); 28 | n = (x + 4) / 5; 29 | dn = sqrt((double)n); 30 | for (i = 1; i <= (long long)dn + 1; i++) 31 | { 32 | u1 = n / i; 33 | u2 = n / i + 1; 34 | if (u1 * i < n) 35 | u1 = u2; 36 | 37 | if (area(i, u1) < ans) 38 | a = i, b = u1, ans = area(i, u1); 39 | } 40 | aa = 10 * max(a, b) + 2; 41 | bb = 44 * min(a, b) + 4; 42 | if (aa < bb) 43 | swap(aa, bb); 44 | printf("%lld X %lld = %lld\n", aa, bb, ans); 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /ICPC.Regional/2007.Northwestern_Europe/la3979.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Nouthwestern Europe: Tower Parking 2 | // ACM-ICPC Live Archive 3979 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | void solve(){ 9 | int h, l, x, ans = 0; 10 | scanf("%d%d", &h, &l); 11 | for (int i = 0; i < h; i++){ 12 | vector< pair > park; 13 | for (int j = 0; j < l; j++){ 14 | scanf("%d", &x); 15 | if (x != -1) 16 | park.push_back(make_pair(x, j)); 17 | } 18 | sort(park.begin(), park.end()); 19 | for (int j = 0, gate = 0; j < (int)park.size(); j++){ 20 | int d = park[j].second - gate > 0 ? park[j].second - gate : gate - park[j].second; 21 | ans += min(d, l - d) * 5; 22 | gate = park[j].second; 23 | } 24 | ans += i * 20 * park.size(); 25 | } 26 | printf("%d\n", ans); 27 | } 28 | 29 | int main() { 30 | int T; 31 | scanf("%d\n", &T); 32 | while (T--) 33 | solve(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ICPC.Regional/2007.Seoul/la3900.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Seoul: Molar mass 2 | // ACM-ICPC Live Archive 3900 3 | #include 4 | #include 5 | #define C 12.01 6 | #define N 14.01 7 | #define O 16.00 8 | #define H 1.008 9 | char cmd[100000], num[5]; 10 | bool isletter(char ch) { 11 | return ch >= 'A' && ch <= 'Z'; 12 | } 13 | 14 | void solve() { 15 | double ans = 0; 16 | int i, j, len, x; 17 | char pre = 0; 18 | scanf("%s", cmd); 19 | len = strlen(cmd); 20 | for (i = 0; i < len; i++) { 21 | if (isletter(cmd[i])) { 22 | if (pre) { 23 | if (j) { 24 | num[j] = 0; 25 | sscanf(num, "%d", &x); 26 | } else x = 1; 27 | if (pre == 'N') ans += (double) x * N; 28 | else if (pre == 'O') ans += (double) x * O; 29 | else if (pre == 'C') ans += (double) x * C; 30 | else if (pre == 'H') ans += (double) x * H; 31 | } 32 | j = 0; 33 | pre = cmd[i]; 34 | } else num[j++] = cmd[i]; 35 | } 36 | if (pre) { 37 | if (j) { 38 | num[j] = 0; 39 | sscanf(num, "%d", &x); 40 | } else x = 1; 41 | if (pre == 'N') ans += (double) x * N; 42 | else if (pre == 'O') ans += (double) x * O; 43 | else if (pre == 'C') ans += (double) x * C; 44 | else if (pre == 'H') ans += (double) x * H; 45 | } 46 | printf("%.3lf\n", ans); 47 | } 48 | int main() { 49 | int T; 50 | scanf("%d", &T); 51 | while (T--) 52 | solve(); 53 | return 0; 54 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Seoul/la3904.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Seoul: Tile Code 2 | // ACM-ICPC Live Archive 3904 3 | #include 4 | #include 5 | #define N 35 6 | long long f[N], s[N]; 7 | void pre() { 8 | int i; 9 | f[1] = 1, f[2] = 3; 10 | for (i = 3; i <= 30; i++) 11 | f[i] = f[i - 2] * 2 + f[i - 1]; 12 | for (i = 3; i <= 30; i++) { 13 | if (i % 2) s[i] = f[(i - 1) / 2]; 14 | else s[i] = 2 * f[(i - 2) / 2] + f[i / 2]; 15 | } 16 | } 17 | int main() { 18 | pre(); 19 | int T, x; 20 | scanf("%d", &T); 21 | while (T--) { 22 | scanf("%d", &x); 23 | printf("%lld\n", (s[x] + f[x]) / 2); 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Tokyo/img/3885_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2007.Tokyo/img/3885_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2007.Tokyo/img/3886_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2007.Tokyo/img/3886_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2007.Tokyo/la3882.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Tokyo: And Then There Was One 2 | // ACM-ICPC Live Archive 3882 3 | // POJ 3517 4 | #include 5 | int main() { 6 | int n, k, m; 7 | while (scanf("%d%d%d", &n, &k, &m) && n) { 8 | int i, s = 0; 9 | for (i = 2; i < n; i++) 10 | s = (s + k) % i; 11 | s = (s + m) % n; 12 | printf("%d\n", s + 1); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Tokyo/la3883.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Tokyo: Prime Gap 2 | // ACM-ICPC Live Archive 3883 3 | // POJ 3518 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define MAX_N 1299719+10 9 | bool primes[MAX_N]; 10 | int solve(int n) { 11 | int gap = 0, i; 12 | if (primes[n]) 13 | return 0; 14 | for (i = n + 1; !primes[i]; i++) 15 | gap++; 16 | for (i = n - 1; !primes[i]; i--) 17 | gap++; 18 | return gap + 2; 19 | } 20 | 21 | int main() { 22 | int n; 23 | memset(primes, 0, sizeof(primes)); 24 | for (int i = 2; i <= MAX_N / 2; i++) 25 | primes[i] = true; 26 | 27 | for (int i = 2; i < MAX_N; i++) { 28 | if (primes[i]) { 29 | for (int j = 2; i * j < MAX_N; j++) 30 | primes[i * j] = false; 31 | } 32 | } 33 | 34 | while (scanf("%d", &n) && n) 35 | printf("%d\n", solve(n)); 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Tokyo/la3884.cpp: -------------------------------------------------------------------------------- 1 | // 2007 Tokyo: Minimal Backgammon 2 | // ACM-ICPC Live Archive 3884 3 | // POJ 3519 4 | #include 5 | #include 6 | #define N 105 7 | int n, T, nl, nb; 8 | double dp[N][N]; 9 | bool lose[N], back[N]; 10 | double solve() { 11 | int i, t, j, x; 12 | double ans = 0; 13 | memset(dp, 0, sizeof(dp)); 14 | memset(lose, 0, sizeof(lose)); 15 | memset(back, 0, sizeof(back)); 16 | for (i = 0; i < nl; i++) { 17 | scanf("%d", &x); 18 | lose[x] = 1; 19 | } 20 | for (i = 0; i < nb; i++) { 21 | scanf("%d", &x); 22 | back[x] = 1; 23 | } 24 | dp[0][0] = 1.0; 25 | for (t = 0; t < T; t++) { 26 | for (i = 0; i < n; i++) { 27 | if (back[i]) continue; 28 | for (j = 1; j <= 6; j++) { 29 | int next = i + j; 30 | if (next > n) next = n - (j - (n - i)); 31 | if (lose[i]) { 32 | if (back[next]) dp[t + 2][0] += dp[t][i] / 6.0; 33 | else dp[t + 2][next] += dp[t][i] / 6.0; 34 | } else { 35 | if (back[next]) dp[t + 1][0] += dp[t][i] / 6.0; 36 | else dp[t + 1][next] += dp[t][i] / 6.0; 37 | } 38 | } 39 | } 40 | } 41 | for(i = 1; i <= T;i++) 42 | ans += dp[i][n]; 43 | return ans; 44 | } 45 | int main() { 46 | //freopen("in.txt", "r", stdin); 47 | while (scanf("%d%d%d%d", &n, &T, &nl, &nb) && n) 48 | printf("%.7lf\n", solve()); 49 | return 0; 50 | } -------------------------------------------------------------------------------- /ICPC.Regional/2007.Tokyo/la3891.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2007.Tokyo/la3891.cpp -------------------------------------------------------------------------------- /ICPC.Regional/2008.Aizu/4158.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Aizu: Expected Allowance 2 | // ACM-ICPC Live Archive 4158 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 1000 8 | int dp[50][N]; 9 | int main() { 10 | int n, m, k, i, j, u; 11 | while (scanf("%d%d%d", &n, &m, &k) && n) { 12 | memset(dp, 0, sizeof(dp)); 13 | for (i = 1; i <= m; i++) 14 | dp[1][i] = 1; 15 | for (i = 2; i <= n; i++) 16 | for (j = i; j <= i * m; j++) { 17 | for (u = j - 1; u >= j - m; u--) { 18 | if (u == 0) break; 19 | dp[i][j] += dp[i - 1][u]; 20 | } 21 | } 22 | double base = 1, ans = 0; 23 | for (i = 1; i <= n; i++) 24 | base *= m; 25 | for (i = n; i <= n * m; i++) 26 | if (i - k <= 0) ans += dp[n][i] / base; 27 | else ans += dp[n][i] / base * (i - k); 28 | 29 | printf("%.10lf\n", ans); 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Amritapuri/la4334.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Amritapuri: Gold Digging 2 | // ACM-ICPC Live Archive 4334 3 | #include 4 | #include 5 | using namespace std; 6 | #define EPS 1e-10 7 | int n; 8 | int sgn(double x) { 9 | return x < -EPS ? -1 : x > EPS; 10 | } 11 | struct NODE { 12 | double sum, po, ok, se, ex; 13 | bool operator <(const NODE &p) const { 14 | return se < p.se; 15 | } 16 | }; 17 | 18 | void solve() { 19 | priority_queue Q; 20 | while(n--) { 21 | NODE x; 22 | scanf("%lf%lf%lf", &x.ok, &x.po, &x.sum); 23 | x.ok /= 100.0, x.po /= 100.0; 24 | x.ok = 1 - x.ok; 25 | x.ex = x.ok * x.po * x.sum; 26 | x.se = x.ex / (1 - x.ok); 27 | Q.push(x); 28 | } 29 | double k = 1, ans = 0; 30 | while (!Q.empty()) { 31 | NODE x; 32 | x = Q.top(); 33 | Q.pop(); 34 | if (k * x.ex < EPS) break; 35 | ans += k * x.ex; 36 | k *= x.ok; 37 | if (x.po != 1) { 38 | x.sum *= (1 - x.po); 39 | x.ex = x.ok * x.po * x.sum; 40 | x.se = x.ex / (1 - x.ok); 41 | Q.push(x); 42 | } 43 | } 44 | printf("%.6lf\n", ans); 45 | } 46 | int main() { 47 | while (scanf("%d", &n) && n != -1) 48 | solve(); 49 | return 0; 50 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Amritapuri/la4335.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Amritapuri: Minesweeper 2 | // ACM-ICPC Live Archive 4335 3 | #include 4 | #define N 25 5 | char ch[N][N]; 6 | int n, m; 7 | int dx[] = { 1, 1, 1, 0, 0, -1, -1, -1 }; 8 | int dy[] = { 1, 0, -1, 1, -1, 1, 0, -1 }; 9 | int calc(int x, int y) { 10 | int ans = 0, i; 11 | for (i = 0; i < 8; i++) { 12 | int nx = x + dx[i]; 13 | int ny = y + dy[i]; 14 | if (nx == -1 || ny == -1 || nx == n || ny == m) continue; 15 | ans += ch[nx][ny] == 'F'; 16 | } 17 | return ans; 18 | } 19 | bool check(int x, int y) { 20 | for (int i = 0; i < 8; i++) { 21 | int nx = x + dx[i]; 22 | int ny = y + dy[i]; 23 | if (nx == -1 || ny == -1 || nx == n || ny == m) continue; 24 | if (ch[nx][ny] != 'F') return 1; 25 | } 26 | return 0; 27 | } 28 | int solve() { 29 | int i, j; 30 | scanf("%d%d\n", &n, &m); 31 | for (i = 0; i < n; i++) 32 | scanf("%s", ch[i]); 33 | for (i = 0; i < n; i++) 34 | for (j = 0; j < m; j++) { 35 | if (ch[i][j] == 'F') { 36 | if (!check(i, j)) return 0; 37 | } else if (calc(i, j) != ch[i][j] - '0') return 0; 38 | 39 | } 40 | return 1; 41 | } 42 | int main() { 43 | int T; 44 | scanf("%d", &T); 45 | while (T--) 46 | puts(solve() ? "Well done Clark!" : "Please sweep the mine again!"); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Amritapuri/la4336.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Amritapuri: Palindromic paths 2 | // ACM-ICPC Live Archive 4336 3 | #include 4 | #include 5 | #define N 55 6 | char ch[N][N]; 7 | char dp[N][N][N]; 8 | void f(int a, int b) { 9 | if (a == b) return; 10 | if (dp[a][b][0] != 0) return; 11 | dp[a][b][0] = ch[a][b]; 12 | for (int i = a + 1; i < b; i++) { 13 | for (int j = b - 1; j >= i; j--) 14 | if (ch[a][i] == ch[j][b]) { 15 | char s[N] = { 0 }; 16 | f(i, j); 17 | int l1 = strlen(dp[i][j]) + 2; 18 | int l2 = strlen(dp[a][b]); 19 | if (l1 < l2) continue; 20 | strcpy(s + 1, dp[i][j]); 21 | s[0] = ch[a][i]; 22 | s[strlen(s)] = ch[a][i]; 23 | if (l1 > l2) strcpy(dp[a][b], s); 24 | else if (strcmp(s, dp[a][b]) < 0) strcpy(dp[a][b], s); 25 | } 26 | } 27 | } 28 | void solve() { 29 | int n, i; 30 | scanf("%d", &n); 31 | for (i = 0; i < n; i++) 32 | scanf("%s", ch[i]); 33 | memset(dp, 0, sizeof(dp)); 34 | f(0, n - 1); 35 | printf("%s\n", dp[0][n - 1]); 36 | } 37 | 38 | int main() { 39 | int T; 40 | scanf("%d", &T); 41 | while (T--) 42 | solve(); 43 | return 0; 44 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Amritapuri/la4337.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Amritapuri: Pile it down 2 | // ACM-ICPC Live Archive 4337 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 1010 8 | int t[N][N], sg[N][N]; 9 | int checkmin(int a, int b) { 10 | if (a == -1) return b; 11 | return min(a, b); 12 | } 13 | void calc() { 14 | int i, j, k, x, y, n = 1000; 15 | int dx[] = { 0, 1, 1 }; 16 | int dy[] = { 1, 0, 1 }; 17 | memset(t, -1, sizeof(t)); 18 | memset(sg, 0, sizeof(sg)); 19 | t[0][0] = 0; 20 | for (i = 1; i <= n; i++) 21 | t[i][0] = sg[i][0] = t[0][i] = sg[0][i] = t[i][i] = sg[i][i] = 1; 22 | for (i = 1; i <= n; i++) { 23 | for (j = 1; j <= n; j++) { 24 | if (sg[i][j]) continue; 25 | t[i][j] = 1; 26 | for (k = 0; k < 3; k++) { 27 | x = i - dx[k], y = j - dy[k]; 28 | while (x >= 0 && y >= 0) { 29 | t[i][j] = max(t[i][j], t[x][y] + 1); 30 | x -= dx[k], y -= dy[k]; 31 | } 32 | } 33 | for (k = 0; k < 3; k++) { 34 | x = i + dx[k], y = j + dy[k]; 35 | while (x <= n && y <= n) { 36 | t[x][y] = checkmin(t[x][y], t[i][j] + 1); 37 | sg[x][y] = 1; 38 | x += dx[k], y += dy[k]; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | int main() { 45 | calc(); 46 | int T, x, y, p; 47 | scanf("%d", &T); 48 | while (T--) { 49 | scanf("%d%d%d", &x, &y, &p); 50 | if (sg[x][y]) printf("Sita %d\n", t[x][y] + 2 * p); 51 | else printf("Gita %d\n", t[x][y] + 2 * p); 52 | } 53 | return 0; 54 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Amritapuri/la4340.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Amritapuri: Find Terrorists 2 | // ACM-ICPC Live Archive 4340 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | const int maxsz = 10005; 9 | const int maxsz2 = maxsz / 2; 10 | const int maxsqrt = sqrt(double(maxsz)) / 2; 11 | char a[maxsz / 16 + 2]; 12 | 13 | 14 | inline int isprime(int n) { 15 | return ((n & 1) || (2 == n)) && (a[(n) >> 4] & (1 << (((n) >> 1) & 7))); 16 | } 17 | void sieve() { 18 | memset(a, 255, sizeof a); 19 | a[0] = 0xFE; 20 | for (int i = 1; i < maxsqrt; i++) 21 | if (a[i >> 3] & (1 << (i & 7))) for (int j = i + i + i + 1; j < maxsz2; j += i + i + 1) 22 | a[j >> 3] &= ~(1 << (j & 7)); 23 | } 24 | #define N 10005 25 | int cnt[N]; 26 | int calc(int x) { 27 | if (cnt[x] != -1) return cnt[x]; 28 | int i, sum = 0; 29 | for (i = 1; i <= x; i++) 30 | if (x % i == 0) sum++; 31 | return cnt[x] = isprime(sum); 32 | } 33 | void solve() { 34 | int l, h, i, ok = 0; 35 | scanf("%d%d", &l, &h); 36 | cnt[1] = 0; 37 | for (i = l; i <= h; i++) { 38 | if (calc(i)) { 39 | if (ok) printf(" "); 40 | printf("%d", i); 41 | ok = 1; 42 | } 43 | } 44 | if (!ok) printf("-1"); 45 | printf("\n"); 46 | } 47 | int main() { 48 | sieve(); 49 | int T; 50 | memset(cnt, -1, sizeof(cnt)); 51 | scanf("%d", &T); 52 | while (T--) 53 | solve(); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Beijing/la4328.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Beijing: Priest John's Busiest Day 2 | // ACM-ICPC Live Archive 4328 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | struct NODE { 8 | long long b, e, m, len; 9 | bool operator<(const NODE &n) const { 10 | if (m == n.m) return len > n.len; 11 | return m < n.m; 12 | } 13 | }; 14 | #define N 100005 15 | NODE ll[N]; 16 | int main() { 17 | int n; 18 | while (scanf("%d", &n) && n) { 19 | int ok = 1, i; 20 | long long end; 21 | for (i = 0; i < n; i++) { 22 | scanf("%lld%lld", &ll[i].b, &ll[i].e); 23 | long long len = ll[i].e - ll[i].b + 1; 24 | ll[i].m = ll[i].b + len / 2 + len % 2 - 1; 25 | ll[i].len = len; 26 | } 27 | sort(ll, ll + n); 28 | end = ll[0].m + 1; 29 | for (i = 1; i < n && ok; i++) { 30 | end = max(end, ll[i].b) + ll[i].len / 2 + ll[i].len % 2; 31 | if (end > ll[i].e) ok = 0; 32 | } 33 | puts(ok ? "YES" : "NO"); 34 | } 35 | return 0; 36 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Beijing/la4330.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Beijing: Timer 2 | // ACM-ICPC Live Archive 4330 3 | #include 4 | #include 5 | #define PI 3.141592653589793 6 | double H, R, V; 7 | double v(double h) { 8 | double k = R - h; 9 | double ans = H * R * R * acos(k / R) - 2 * k * H * sqrt(R * R - k * k) + k * k * k * H * log((R + sqrt(R * R - k * k)) / k)/ R; 10 | return ans / 3.0; 11 | } 12 | int main() { 13 | int T; 14 | scanf("%d", &T); 15 | while (T--) { 16 | double l, r, mid; 17 | scanf("%lf%lf%lf", &H, &R, &V); 18 | R /= 2.0; 19 | l = 0, r = R; 20 | while (r - l >= 1e-6) { 21 | mid = (l + r) / 2.0; 22 | if (v(mid) > V) r = mid; 23 | else l = mid; 24 | } 25 | printf("%.5lf\n", 2 * R - (l + r)/2.0); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Chengdu/la4401.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Chengdu: String painter 2 | // ACM-ICPC Live Archive 4394 3 | #include 4 | #include 5 | #define N 105 6 | #define M 27 7 | int dp[N][N][M]; 8 | char A[N], B[N]; 9 | int dfs(int l, int r, int ch) { 10 | int c, t, i; 11 | if (dp[l][r][ch] == -1) { 12 | if (ch) c = ch; 13 | else c = A[l]; 14 | if (c == B[l]) dp[l][r][ch] = dfs(l+1, r, ch); 15 | else { 16 | dp[l][r][ch] = dfs(l + 1, r, ch) + 1; 17 | for (i = l + 1; i <= r; i++) { 18 | if (B[l] != B[i]) continue; 19 | t = dfs(l + 1, i - 1, B[l]) + dfs(i + 1, r, ch) + 1; 20 | dp[l][r][ch] = dp[l][r][ch] < t ? dp[l][r][ch] : t; 21 | } 22 | } 23 | } 24 | return dp[l][r][ch]; 25 | } 26 | int main() { 27 | while (~scanf("%s", A)) { 28 | scanf("%s", B); 29 | int n = strlen(A), i, j, k; 30 | for (i = 0; i < n; i++) 31 | A[i] = A[i] - 'a' + 1, B[i] = B[i] - 'a' + 1; 32 | for (i = 0; i < n; i++) 33 | for (j = i; j < n; j++) 34 | for (k = 0; k < M; k++) { 35 | if (i == j) { 36 | if (!k) dp[i][j][k] = A[i] != B[i]; 37 | else dp[i][j][k] = k != B[i]; 38 | } else dp[i][j][k] = -1; 39 | } 40 | printf("%d\n", dfs(0, n - 1, 0)); 41 | } 42 | return 0; 43 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Dhaka/img/4203_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Dhaka/img/4203_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Dhaka/la4202.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Dhaka: Schedule of a Married Man 2 | // ACM-ICPC Live Archive 4202 3 | #include 4 | int main() { 5 | int T, h1, m1, h2, m2, ca = 1; 6 | int t1, t2, t3, t4; 7 | scanf("%d", &T); 8 | while (T--) { 9 | scanf("%d:%d %d:%d", &h1, &m1, &h2, &m2); 10 | t1 = h1 * 60 + m1; 11 | t2 = h2 * 60 + m2; 12 | scanf("%d:%d %d:%d", &h1, &m1, &h2, &m2); 13 | t3 = h1 * 60 + m1; 14 | t4 = h2 * 60 + m2; 15 | 16 | printf("Case %d: ", ca++); 17 | if (t1 > t4 || t2 < t3) printf("Hits Meeting\n"); 18 | else printf("Mrs Meeting\n"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Dhaka/la4205.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Dhaka: Clicking Checkboxes 2 | // ACM-ICPC Live Archive 4205 3 | #include 4 | #include 5 | #define N 65 6 | 7 | long long dp[N][N][N][2]; 8 | // dp[n][x][c][top]: the way of layouts when: 9 | // n: total number of checkboxes 10 | // x: total number of boxes should be checked. 11 | // c: changing time from checked to unchecked, and unchecked to checked. 12 | // top: whether the first box is checked (top = 1) or not (top = 0). 13 | 14 | void init(){ 15 | int n = 64; 16 | memset(dp, 0, sizeof(dp)); 17 | dp[1][1][1][1] = dp[1][0][0][0] = 1; 18 | for (int i = 2; i <= n; i++){ 19 | for (int x = 0; x <= n; x++){ 20 | for (int c = 0; c <= n; c++){ 21 | if (c - 2 >= 0 && x - 1 >= 0) 22 | dp[i][x][c][1] += dp[i - 1][x - 1][c - 2][0]; 23 | if (x - 1 >= 0) 24 | dp[i][x][c][1] += dp[i - 1][x - 1][c][1]; 25 | dp[i][x][c][0] = dp[i - 1][x][c][0] + dp[i - 1][x][c][1]; 26 | } 27 | } 28 | } 29 | } 30 | 31 | int main(){ 32 | int n, m, T = 0; 33 | init(); 34 | while (scanf("%d%d", &n, &m) && n){ 35 | long long ans1 = 0, ans2 = 0; 36 | for (int i = m; i <= n; i++){ 37 | for (int j = 0; j < i; j++) 38 | ans1 += dp[n][i][j][0] + dp[n][i][j][1]; 39 | for (int j = i + 1; j <= n; j++) 40 | ans2 += dp[n][i][j][0] + dp[n][i][j][1]; 41 | } 42 | printf("Case %d: %lld %lld\n", ++T, ans1, ans2); 43 | } 44 | return 0; 45 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Dhaka/la4209.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Dhaka: Stopping Doom's Day 2 | // ACM-ICPC Live Archive 4209 3 | #include 4 | #define M 10007 5 | typedef long long ll; 6 | ll gcdext(ll a, ll b, ll &x, ll &y) { 7 | if (!b) { 8 | x = 1, y = 0; 9 | return a; 10 | } 11 | ll r = gcdext(b, a % b, x, y); 12 | ll t = x; 13 | x = y; 14 | y = t - a / b * y; 15 | return r; 16 | } 17 | ll modular_linear_equation(ll a, ll b, ll n) { 18 | ll d, x, y; 19 | d = gcdext(a, n, x, y); 20 | if (b % d) return -1; 21 | x *= (b / d); 22 | x = (x % (n / d) + n / d) % (n / d); 23 | return x; 24 | } 25 | ll mod_exp(ll a, ll b, ll n) { 26 | ll hash = 1, factor = a, x = b; 27 | while (x) { 28 | if (x & 1) hash = (hash * factor) % n; 29 | factor = (factor * factor) % n; 30 | x >>= 1; 31 | } 32 | return hash; 33 | } 34 | int main() { 35 | ll n, ans; 36 | while (scanf("%lld", &n) != EOF, n) { 37 | //y = (107/22680)x^10 + (23/-756)x^8 + (71/1080)x^6 +(103/-1134)x^4 + (16/315)x^2 38 | ans = mod_exp(n, 10, M) * 107 * modular_linear_equation(22680, 1, M) % M; 39 | ans -= mod_exp(n, 8, M) * 23 * modular_linear_equation(756, 1, M) % M; 40 | ans += mod_exp(n, 6, M) * 71 * modular_linear_equation(1080, 1, M) % M; 41 | ans -= mod_exp(n, 4, M) * 103 * modular_linear_equation(1134, 1, M) % M; 42 | ans += mod_exp(n, 2, M) * 16 * modular_linear_equation(315, 1, M) % M; 43 | ans = (ans + M) % M; 44 | ans = (ans + M) % M; 45 | printf("%lld\n", ans); 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Hangzhou/la4351.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hangzhou: A Pair of Graphs 2 | // ACM-ICPC Live Archive 4351 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 9 8 | bool g1[N][N], g2[N][N]; 9 | int n, m1, m2, arr[N]; 10 | void solve() { 11 | int a, b, i, j, ia, ib, da, db, t, ans = 1 << 29; 12 | scanf("%d%d%d%d", &ia, &ib, &da, &db); 13 | memset(g1, 0, sizeof(g1)); 14 | memset(g2, 0, sizeof(g2)); 15 | for (i = 0; i < m1; i++) { 16 | scanf("%d%d", &a, &b); 17 | g1[a][b] = g1[b][a] = 1; 18 | } 19 | for (i = 0; i < m2; i++) { 20 | scanf("%d%d", &a, &b); 21 | g2[a][b] = g2[b][a] = 1; 22 | } 23 | if (n > 1) { 24 | for (i = 0; i < n; i++) 25 | arr[i] = i; 26 | while (next_permutation(arr, arr + n)) { 27 | t = 0; 28 | for (i = 0; i < n; i++) 29 | for (j = i + 1; j < n; j++) { 30 | a = arr[i], b = arr[j]; 31 | if (g1[a][b] == g2[i][j]) 32 | continue; 33 | if (!g1[a][b] && g2[i][j]) 34 | t += min(ia, db); 35 | else 36 | t += min(ib, da); 37 | } 38 | ans = min(ans, t); 39 | } 40 | } else 41 | ans = 0; 42 | printf("%d\n", ans); 43 | } 44 | int main() { 45 | int T = 0; 46 | while (scanf("%d%d%d", &n, &m1, &m2) && n) { 47 | printf("Case #%d: ", ++T); 48 | solve(); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Hangzhou/la4357.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hangzhou: Get-Together at Stockholm 2 | // ACM-ICPC Live Archive 4357 3 | #include 4 | #include 5 | #define N 105 6 | bool g[N][N]; 7 | int n, m, a, b, ans, v[N]; 8 | int find() { 9 | int i, j; 10 | for (i = 0; i < n; i++) { 11 | int ta = 0, tb = 0; 12 | if (v[i]) continue; 13 | for (j = 0; j < n; j++) 14 | if (!v[j] && i != j) ta += g[i][j], tb += !g[i][j]; 15 | if (ta < a || tb < b) return i; 16 | } 17 | return -1; 18 | } 19 | 20 | void del(int x) { 21 | ans--, v[x] = 1; 22 | for (int i = 0; i < n; i++) 23 | g[x][i] = g[i][x] = 0; 24 | } 25 | void solve() { 26 | int x; 27 | memset(g, 0, sizeof(g)); 28 | memset(v, 0, sizeof(v)); 29 | while (m--) { 30 | int a, b; 31 | scanf("%d%d", &a, &b); 32 | g[a][b] = g[b][a] = 1; 33 | } 34 | ans = n; 35 | while ((x = find()) != -1) 36 | del(x); 37 | printf("%d\n", ans); 38 | 39 | } 40 | int main() { 41 | int T = 0; 42 | while (scanf("%d%d%d%d", &n, &m, &a, &b) && n) { 43 | printf("Case #%d: ", ++T); 44 | solve(); 45 | } 46 | return 0; 47 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Hangzhou/la4360.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hangzhou: Junk-Mail Filter 2 | // ACM-ICPC Live Archive 4360 3 | #include 4 | #include 5 | #define N 1000000 6 | #define M 100005 7 | int fa[N], rank[N], root[N]; 8 | bool ans[N]; 9 | void init_set(int n) { 10 | for (int i = 0; i <= n; i++) 11 | root[i] = fa[i] = i, rank[i] = 0; 12 | } 13 | int find_root(int p) { 14 | if (fa[p] != p) fa[p] = find_root(fa[p]); 15 | return fa[p]; 16 | } 17 | void union_set(int p, int q) { 18 | int a = find_root(p), b = find_root(q); 19 | if (a == b) return; 20 | if (rank[a] > rank[b]) fa[b] = a; 21 | else if (rank[a] < rank[b]) fa[a] = b; 22 | else fa[b] = a, rank[a]++; 23 | } 24 | int main() { 25 | int n, m, T = 0, i; 26 | while (scanf("%d%d\n", &n, &m) && n) { 27 | int p = n, a, b; 28 | char op; 29 | init_set(n); 30 | while (m--) { 31 | scanf("%c", &op); 32 | if (op == 'M') { 33 | scanf("%d%d\n", &a, &b); 34 | union_set(root[a], root[b]); 35 | } else { 36 | scanf("%d\n", &a); 37 | root[a] = p++; 38 | rank[root[a]] = 0; 39 | fa[root[a]] = root[a]; 40 | } 41 | } 42 | memset(ans, 0, sizeof(ans)); 43 | int cnt = 0; 44 | for(i = 0; i < n; i++) 45 | { 46 | int k = find_root(root[i]); 47 | if(!ans[k]) 48 | ans[k] = 1, cnt++; 49 | } 50 | printf("Case #%d: %d\n", ++T,cnt ); 51 | } 52 | return 0; 53 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Harbin/la4320.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Harbin: Degree Sequence of Graph G 2 | // ACM-ICPC Live Archive 4320 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 1005 9 | int deg[N]; 10 | bool cmp(const int &a, const int &b) { 11 | return a > b; 12 | } 13 | int solve() { 14 | int n, i, t; 15 | scanf("%d", &n); 16 | for (i = 0; i < n; i++) 17 | scanf("%d", deg + i); 18 | sort(deg, deg + n, cmp); 19 | for (t = 0; t < n; t++) { 20 | for (i = 1; i < n && deg[0]; i++) 21 | if (deg[i] > 0) deg[i]--, deg[0]--; 22 | if (deg[0]) return 0; 23 | sort(deg, deg + n - t, cmp); 24 | } 25 | return 1; 26 | } 27 | int main() { 28 | int T; 29 | scanf("%d", &T); 30 | while (T--) 31 | puts(solve() ? "yes" : "no"); 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Hefei/img/4275_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Hefei/img/4275_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Hefei/la4275.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Hefei: Rational Number Approximation 2 | // ACM-ICPC Live Archive 4275 3 | 4 | #include 5 | long long gcd(long long m, long long n) { 6 | long long r; 7 | while (n > 0) { 8 | r = m % n; 9 | m = n; 10 | n = r; 11 | } 12 | return m; 13 | } 14 | int main() { 15 | long long a, b, n; 16 | int T = 0; 17 | while (scanf("%lld%lld%lld", &a, &b, &n) && (a + b)) { 18 | long long x1, x3, y1, y3, x2, y2, gd, l, r, m, k1, k2; 19 | gd = gcd(a, b); 20 | a /= gd, b /= gd; 21 | printf("Case %d: ", ++T); 22 | if (b <= n) { 23 | printf("%lld/%lld %lld/%lld\n", a, b, a, b); 24 | continue; 25 | } 26 | x1 = 0, y1 = 1, x3 = 1, y3 = 1; 27 | while (1) { 28 | x2 = x1 + x3, y2 = y1 + y3; 29 | if (y2 > n) break; 30 | l = 1, r = n; 31 | if (a * y2 < b * x2) { 32 | while (l < r) { 33 | m = (l + r + 1) / 2; 34 | k1 = m * x1 + x3, k2 = m * y1 + y3; 35 | if (m * y1 + y3 > n || k1 * b < k2 * a) r = m - 1; 36 | else l = m; 37 | } 38 | x3 = l * x1 + x3, y3 = l * y1 + y3; 39 | } else { 40 | while (l < r) { 41 | m = (l + r + 1) / 2; 42 | k1 = x1 + m * x3, k2 = y1 + m * y3; 43 | if (y1 + m * y3 > n || k1 * b > k2 * a) r = m - 1; 44 | else l = m; 45 | } 46 | x1 = x1 + l * x3, y1 = y1 + l * y3; 47 | } 48 | } 49 | printf("%lld/%lld %lld/%lld\n", x1, y1, x3, y3); 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Jakarta/la4139.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Jakarta: Bonus Treasure 2 | // ACM-ICPC Live Archive 4139 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | void print(long long s, long long l, long long r) { 8 | long long i, p, q; 9 | if (s == 1) { 10 | if (l == 0 && r == 1) printf("()"); 11 | else if (l == r && l == 0) printf("("); 12 | else printf(")"); 13 | return; 14 | } 15 | if (l == 0) { 16 | printf("("); 17 | l++; 18 | } 19 | p = 1LL; 20 | for (i = 1; i < s; i++) { 21 | q = p + (1LL << i) - 1LL; 22 | if (l > q || r < p) { 23 | p += (1LL << i); 24 | continue; 25 | } 26 | print(i, max(0LL, l - p), min(r - p, (1LL << i) - 1LL)); 27 | p += (1LL << i); 28 | } 29 | if (r == (1LL << s) - 1) printf(")"); 30 | } 31 | 32 | int main() { 33 | long long s, l, r; 34 | while (scanf("%lld%lld%lld", &s, &l, &r) && s) { 35 | print(s, l, l + r - 1); 36 | printf("\n"); 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Jakarta/la4142.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Jakarta: Greatest Expert Enough? 2 | // ACM-ICPC Live Archive 4142 3 | #include 4 | #define N 10005 5 | 6 | char name[N][30]; 7 | int seg[N][2]; 8 | void solve() { 9 | int n, i, Q, x; 10 | scanf("%d", &n); 11 | for (i = 0; i < n; i++) 12 | scanf("%s%d%d", name[i], &seg[i][0], &seg[i][1]); 13 | scanf("%d", &Q); 14 | while (Q--) { 15 | int ok = 0, pos; 16 | scanf("%d", &x); 17 | for (i = 0; i < n && ok < 2; i++) { 18 | if (seg[i][0] <= x && x <= seg[i][1]) ok++, pos = i; 19 | } 20 | if (ok == 0 || ok >= 2) printf("UNDETERMINED\n"); 21 | else printf("%s\n", name[pos]); 22 | } 23 | } 24 | int main() { 25 | int T, st = 1; 26 | scanf("%d", &T); 27 | while (T--) { 28 | if (st == 1) st = 0; 29 | else printf("\n"); 30 | solve(); 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Jakarta/la4144.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Jakarta: Greatest K-Palindrome Substring 2 | // ACM-ICPC Live Archive 4144 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 1005 8 | char s[N]; 9 | void solve() { 10 | int len, k, i, a, b, kk, ans = 1, cur; 11 | scanf("%s%d", s, &k); 12 | len = strlen(s); 13 | for (i = 0; i < len; i++) { 14 | cur = 1; 15 | a = i - 1, b = i + 1, kk = k; 16 | while (kk > 0 && a >= 0 && b < len) { 17 | if (s[a] != s[b]) kk--; 18 | a--, b++; 19 | cur += 2; 20 | } 21 | while (a >= 0 && b < len) { 22 | if (s[a] != s[b]) break; 23 | a--, b++; 24 | cur += 2; 25 | } 26 | ans = max(cur, ans); 27 | } 28 | for (i = 1; i < len; i++) { 29 | cur = 2; 30 | a = i - 2, b = i + 1, kk = k; 31 | if (s[i] != s[i - 1] && k == 0) continue; 32 | if (s[i] != s[i - 1]) kk--; 33 | while (kk > 0 && a >= 0 && b < len) { 34 | if (s[a] != s[b]) kk--; 35 | a--, b++; 36 | cur += 2; 37 | } 38 | while (a >= 0 && b < len) { 39 | if (s[a] != s[b]) break; 40 | a--, b++; 41 | cur += 2; 42 | } 43 | ans = max(cur, ans); 44 | } 45 | printf("%d\n", ans); 46 | } 47 | int main() { 48 | int T; 49 | scanf("%d", &T); 50 | while (T--) 51 | solve(); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Jakarta/la4146.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Jakarta: ICPC Team Strategy 2 | // ACM-ICPC Live Archive 4146 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 13 8 | #define INF 1000000 9 | int tt[3][N]; 10 | int dp[1 << N][3], n; 11 | 12 | void solve() { 13 | int i, j, k, v, tot, ans = 0; 14 | scanf("%d", &n); 15 | for (i = 0; i < 3; i++) 16 | for (j = 0; j < n; j++) 17 | scanf("%d", &tt[i][j]); 18 | memset(dp, -1, sizeof(dp)); 19 | dp[0][0] = dp[0][1] = dp[0][2] = 0; 20 | tot = 1 << n; 21 | for (i = 1; i < tot; i++) 22 | for (j = 0; j < 3; j++) 23 | dp[i][j] = INF; 24 | for (i = 0; i < tot; i++) 25 | for (j = 0; j < 3; j++) { 26 | for (k = 0; k < n; k++) { 27 | if ((i & (1 << k)) == 0) { 28 | for (v = 0; v < 3; v++) { 29 | if (v == j) continue; 30 | dp[i | (1 << k)][v] = min(dp[i | (1 << k)][v], dp[i][j] + tt[v][k]); 31 | } 32 | } 33 | } 34 | } 35 | for (i = 0; i < tot; i++) { 36 | int cnt = 0, j = i; 37 | while (j) { 38 | if (j & 1) cnt++; 39 | j >>= 1; 40 | } 41 | if (cnt <= ans) continue; 42 | for (j = 0; j < 3; j++) 43 | if (dp[i][j] <= 280) ans = cnt; 44 | } 45 | printf("%d\n", ans); 46 | } 47 | int main() { 48 | int T; 49 | scanf("%d", &T); 50 | while (T--) 51 | solve(); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Jakarta/la4147.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Jakarta: Jollybee Tournament 2 | // ACM-ICPC Live Archive 4147 3 | #include 4 | #include 5 | #define N 1050 6 | 7 | int num[N]; 8 | bool temp[N]; 9 | void solve() { 10 | int n, m, i, j, ans = 0, tot, x; 11 | scanf("%d%d", &n, &m); 12 | memset(temp, 0, sizeof(temp)); 13 | for (i = 0; i < m; i++) { 14 | scanf("%d", &x); 15 | temp[x - 1] = 1; 16 | } 17 | m = 0; 18 | for (i = 0; i < (1 << n); i++) 19 | if (temp[i] == 0) num[m++] = i; 20 | for (i = 0; i < n; i++) { 21 | tot = 0; 22 | for (j = 0; j < m; j++) { 23 | if (j + 1 < m && (num[j] ^ 1) == num[j + 1]) { 24 | num[tot++] = num[j] / 2; 25 | j++; 26 | } else { 27 | ans++; 28 | num[tot++] = num[j] / 2; 29 | } 30 | } 31 | m = tot; 32 | } 33 | printf("%d\n", ans); 34 | } 35 | int main() { 36 | int T; 37 | scanf("%d", &T); 38 | while (T--) 39 | solve(); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img2.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img3.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Kuala_Lumpur/img/la4413_img4.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/la4403.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Kuala Lumpur: ASCII Diamondi 2 | // ACM-ICPC Live Archive 4403 3 | #include 4 | #include 5 | int n, x1, x2, y1, y2; 6 | int iabs(int x) { 7 | return x < 0 ? -x : x; 8 | } 9 | void solve() { 10 | int i, j; 11 | scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 12 | for (i = x1; i <= x2; i++) { 13 | for (j = y1; j <= y2; j++) { 14 | int a = i % (2*n-1), b = j % (2*n-1); 15 | int v = iabs(b - (n - 1)) + iabs(a - (n - 1)); 16 | if (v >= n) printf("."); 17 | else printf("%c", 'a' + (v % 26)); 18 | } 19 | printf("\n"); 20 | } 21 | } 22 | int main() { 23 | int T = 1; 24 | //freopen("in.txt", "r", stdin); 25 | while (scanf("%d", &n) && n) { 26 | printf("Case %d:\n", T++); 27 | solve(); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/la4405.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Kuala Lumpur: Tariff Plan 2 | // ACM-ICPC Live Archive 4405 3 | #include 4 | #include 5 | 6 | void solve() { 7 | int s1 = 0, s2 = 0, n, l, x; 8 | scanf("%d", &n); 9 | while (n--) { 10 | scanf("%d", &l); 11 | x = (l + 30) / 30; 12 | s1 += x * 10; 13 | x = (l + 60) / 60; 14 | s2 += x * 15; 15 | } 16 | if (s1 < s2) printf("Mile %d\n", s1); 17 | else if (s2 < s1) printf("Juice %d\n", s2); 18 | else printf("Mile Juice %d\n", s1); 19 | } 20 | int main() { 21 | int T, ca = 1; 22 | scanf("%d", &T); 23 | while (T--) { 24 | printf("Case %d: ", ca++); 25 | solve(); 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/la4408.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Kuala Lumpur: Unlock the Lock 2 | // ACM-ICPC Live Archive 4408 3 | #include 4 | #include 5 | #define N 10005 6 | bool v[N]; 7 | int Q[N]; 8 | int l, u, r; 9 | void solve() { 10 | int i, qh, qe, inq = 1, next, step = 0; 11 | int code[20]; 12 | for (i = 0; i < r; i++) 13 | scanf("%d", code + i); 14 | qh = 0, qe = 0; 15 | memset(v, 0, sizeof(v)); 16 | v[l] = 1; 17 | Q[qe++] = l; 18 | while (qh < qe) { 19 | next = 0; 20 | while (inq--) { 21 | int top = Q[qh++]; 22 | if (top == u) { 23 | printf("%d\n", step); 24 | return; 25 | } 26 | for (i = 0; i < r; i++) { 27 | if (!v[(top + code[i]) % 10000]) { 28 | v[(top + code[i]) % 10000] = 1; 29 | Q[qe++] = (top + code[i]) % 10000; 30 | next++; 31 | } 32 | } 33 | } 34 | step++; 35 | inq = next; 36 | } 37 | printf("Permanently Locked\n"); 38 | } 39 | int main() { 40 | int ca = 1; 41 | while (scanf("%d%d%d", &l, &u, &r) && l + u + r) { 42 | printf("Case %d: ", ca++); 43 | solve(); 44 | } 45 | return 0; 46 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Kuala_Lumpur/la4413.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Kuala Lumpur: Triangle Hazard 2 | // ACM-ICPC Live Archive 4413 3 | #include 4 | #include 5 | struct POINT { 6 | double x, y; 7 | void get() { 8 | scanf("%lf%lf", &x, &y); 9 | } 10 | void print() { 11 | printf("%.8lf %.8lf ", x, y); 12 | } 13 | }; 14 | double dis(POINT &a, POINT &b) { 15 | return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); 16 | } 17 | 18 | POINT menelause(POINT p, POINT q, POINT r, double m1, double m2, double m3, double m4, double m5, double m6) { 19 | POINT ans; 20 | double L, k1, k2, x; 21 | L = dis(q, p); 22 | k1 = (m5 / m6) * (m1 + m2) / m2; 23 | k2 = (m1 + m2) / m1 * (m4 / m3); 24 | k1 = 1 / k1, k2 = 1 / k2; 25 | x = (L + k2 * L) / (k1 - k2); 26 | ans.x = (r.x - p.x) * (x + L) / L + p.x; 27 | ans.y = (r.y - p.y) * (x + L) / L + p.y; 28 | return ans; 29 | } 30 | void solve() { 31 | POINT p, q, r; 32 | double m1, m2, m3, m4, m5, m6; 33 | p.get(); 34 | q.get(); 35 | r.get(); 36 | scanf("%lf%lf%lf%lf%lf%lf", &m1, &m2, &m3, &m4, &m5, &m6); 37 | menelause(p, q, r, m1, m2, m3, m4, m5, m6).print(); 38 | menelause(q, r, p, m3, m4, m5, m6, m1, m2).print(); 39 | menelause(r, p, q, m5, m6, m1, m2, m3, m4).print(); 40 | printf("\n"); 41 | } 42 | int main() { 43 | int T; 44 | scanf("%d", &T); 45 | while (T--) 46 | solve(); 47 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Northwestern_Europe/4286.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Northwestern Europe: Equilibrium Mobile 2 | // ACM-ICPC Live Archive 4286 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | char s[400000]; 10 | map cnt; 11 | int main() { 12 | int T; 13 | //freopen("in.txt", "r", stdin); 14 | scanf("%d", &T); 15 | while (T--) { 16 | int len, i, dep, total = 0, best = 0; 17 | cnt.clear(); 18 | scanf("%s", s); 19 | len = strlen(s); 20 | for (i = dep = 0; i < len;) { 21 | if (s[i] == '[') i++, dep++; 22 | else if (s[i] == ']') i++, dep--; 23 | else if (s[i] == ',') i++; 24 | else { 25 | int x = 0; 26 | while (i < len && s[i] >= '0' && s[i] <= '9') 27 | x = x * 10 + s[i++] - '0'; 28 | total++; 29 | int v = ++cnt[(long long)x << dep]; 30 | best = max(v, best); 31 | } 32 | } 33 | printf("%d\n", total - best); 34 | } 35 | return 0; 36 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Northwestern_Europe/4288.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Northwestern Europe: Cat vs. Dog 2 | // ACM-ICPC Live Archive 4288 3 | #include 4 | #include 5 | #define N 505 6 | 7 | struct ITEM { 8 | char s1[20], s2[20]; 9 | }; 10 | bool g[N][N], v[N]; 11 | int n, link[N]; 12 | ITEM il[N]; 13 | int dfs(int t) { 14 | int i; 15 | for (i = 1; i <= n; i++) { 16 | if (!v[i] && g[t][i]) { 17 | v[i] = 1; 18 | if (link[i] == -1 || dfs(link[i])) { 19 | link[i] = t; 20 | return 1; 21 | } 22 | } 23 | } 24 | return 0; 25 | } 26 | void solve() { 27 | int i, j, ans = 0; 28 | memset(g, 0, sizeof(g)); 29 | scanf("%d%d%d", &i, &j, &n); 30 | for (i = 1; i <= n; i++) 31 | scanf("%s%s", il[i].s1, il[i].s2); 32 | for (i = 1; i <= n; i++) 33 | for (j = i + 1; j <= n; j++) 34 | if (strcmp(il[i].s1, il[j].s2) == 0 || strcmp(il[i].s2, il[j].s1) == 0) g[i][j] = g[j][i] = 1; 35 | memset(link, -1, sizeof(link)); 36 | for (i = 1; i <= n; i++) { 37 | memset(v, 0, sizeof(v)); 38 | ans += dfs(i); 39 | } 40 | printf("%d\n", (n * 2 - ans) / 2); 41 | } 42 | int main() { 43 | int T; 44 | scanf("%d", &T); 45 | while (T--) 46 | solve(); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Northwestern_Europe/4289.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Northwestern Europe: Disgruntled Judge 2 | // ACM-ICPC Live Archive 4289 3 | #include 4 | #include 5 | #define N 10000 6 | #define M 10001 7 | int x[N]; 8 | 9 | int main() { 10 | int n, i, a, b, y, ok; 11 | scanf("%d", &n); 12 | for (i = 0; i < n; i++) 13 | scanf("%d", x + i); 14 | while (1) { 15 | a = rand() % M, b = rand() % M; 16 | y = x[0]; 17 | ok = 1; 18 | for (i = 0; i < n && ok; i++) { 19 | if (x[i] != y) ok = 0; 20 | y = (y * a + b) % M; 21 | y = (y * a + b) % M; 22 | } 23 | if (ok) { 24 | for (i = 0; i < n; i++) 25 | printf("%d\n", (x[i] * a + b) % M); 26 | return 0; 27 | } 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Northwestern_Europe/img/4287_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Northwestern_Europe/img/4287_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southeastern_Europe/la4183.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Southeastern Europe: Stock Exchange 2 | // ACM-ICPC Live Archive 4183 3 | 4 | #include 5 | #include 6 | #define N 100002 7 | int B[N], f[N], a[N]; 8 | int n; 9 | void solve() { 10 | int i, mid, right, left, num, blen, max = 0; 11 | for (i = 1; i <= n; i++) 12 | scanf("%d", &a[i]); 13 | blen = 1; 14 | B[1] = a[1]; 15 | for (i = 1; i <= n; i++) { 16 | num = a[i], left = 1, right = blen; 17 | while (left <= right) { 18 | mid = (left + right) / 2; 19 | if (B[mid] < num) left = mid + 1; 20 | else right = mid - 1; 21 | } 22 | f[i] = left; 23 | B[left] = num; 24 | if (blen < left) blen = left; 25 | if (max < f[i]) max = f[i]; 26 | } 27 | printf("%d\n", max); 28 | } 29 | 30 | int main() { 31 | while (scanf("%d", &n) != EOF) 32 | solve(); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southeastern_Europe/la4187.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Southeastern Europe: Build Your Home 2 | // ACM-ICPC Live Archive 4187 3 | 4 | #include 5 | #include 6 | #include 7 | struct POINT { 8 | double x, y; 9 | void get() { 10 | scanf("%lf%lf", &x, &y); 11 | } 12 | }; 13 | #define NP 20 14 | struct POLY { 15 | int n; 16 | POINT data[NP]; 17 | }; 18 | POLY pl; 19 | double poly_area(POLY &p) { 20 | double s = p.data[0].y * (p.data[p.n - 1].x - p.data[1].x); 21 | for (int i = 1; i < p.n; i++) 22 | s += p.data[i].y * (p.data[i - 1].x - p.data[(i + 1) % p.n].x); 23 | return s / 2; 24 | } 25 | int main() { 26 | int n, i, ans; 27 | while (scanf("%d", &n) && n) { 28 | pl.n = n; 29 | for (i = 0; i < n; i++) 30 | pl.data[i].get(); 31 | if (n <= 2) { 32 | printf("0\n"); 33 | continue; 34 | } 35 | double a = fabs(poly_area(pl)); 36 | ans = (int) (a + 0.5); 37 | printf("%d\n", ans); 38 | } 39 | return 0; 40 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southeastern_Europe/la4188.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Southeastern Europe: Quick Answer 2 | // ACM-ICPC Live Archive 4188 3 | 4 | #include 5 | #include 6 | #define N 30005 7 | 8 | int fa[N], rank[N], root[N]; 9 | void init_set(int n) { 10 | for (int i = 0; i <= n; i++) 11 | root[i] = fa[i] = i, rank[i] = 0; 12 | } 13 | int find_root(int p) { 14 | if (fa[p] != p) fa[p] = find_root(fa[p]); 15 | return fa[p]; 16 | } 17 | void union_set(int p, int q) { 18 | int a = find_root(p), b = find_root(q); 19 | if (a == b) return; 20 | if (rank[a] > rank[b]) fa[b] = a; 21 | else if (rank[a] < rank[b]) fa[a] = b; 22 | else fa[b] = a, rank[a]++; 23 | } 24 | int main() { 25 | int n; 26 | while (scanf("%d\n", &n) != EOF) { 27 | int p = n + 1, a, b; 28 | int n1, n2; 29 | char op; 30 | n1 = n2 = 0; 31 | init_set(n); 32 | while (1) { 33 | scanf("%c", &op); 34 | if (op == 'e') { 35 | printf("%d , %d\n", n1, n2); 36 | break; 37 | } else if (op == 'c') { 38 | scanf("%d%d\n", &a, &b); 39 | union_set(root[a], root[b]); 40 | } else if (op == 'd') { 41 | scanf("%d\n", &a); 42 | root[a] = p++; 43 | rank[root[a]] = 0; 44 | fa[root[a]] = root[a]; 45 | } else if (op == 'q') { 46 | scanf("%d%d\n", &a, &b); 47 | a = root[a], b = root[b]; 48 | if (find_root(a) == find_root(b)) {/*printf("Yes\n");*/n1++;} 49 | else {/*printf("No\n");*/n2++;} 50 | } 51 | } 52 | 53 | } 54 | return 0; 55 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southeastern_Europe/la4189.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Southeastern Europe: Lucky Numbers 2 | // ACM-ICPC Live Archive 4189 3 | 4 | #include 5 | #include 6 | #include 7 | #define MAX 1000000000001LL 8 | using namespace std; 9 | #define N 10100 10 | #define M 1000000 11 | long long ta[N], num[M], S[M]; 12 | int p1, p2, p3; 13 | void dfs(long long n, int d) { 14 | if (d == 12) return; 15 | ta[p1++] = n; 16 | dfs(n * 10 + 4, d + 1); 17 | dfs(n * 10 + 7, d + 1); 18 | } 19 | 20 | void dfs2(int be, long long x) { 21 | long long xx, ll; 22 | int i; 23 | for (i = be; i < p1; i++) { 24 | ll = MAX / x; 25 | if (ll < ta[i]) return; 26 | xx = x * ta[i]; 27 | num[p2++] = xx; 28 | dfs2(i, xx); 29 | } 30 | } 31 | int solve() { 32 | long long a, b; 33 | int ans; 34 | pair pa, pb; 35 | scanf("%lld%lld", &a, &b); 36 | pa = equal_range(S, S + p3, a); 37 | pb = equal_range(S, S + p3, b); 38 | ans = pb.second - pa.first; 39 | return ans; 40 | 41 | } 42 | void init() { 43 | int i; 44 | p1 = p2 = p3 = 0; 45 | dfs(4, 0); 46 | dfs(7, 0); 47 | sort(ta, ta + p1); 48 | dfs2(0, 1); 49 | sort(num, num + p2); 50 | for (i = 0; i < p2; i++) 51 | if (i == 0 || (i && num[i] != num[i - 1])) S[p3++] = num[i]; 52 | } 53 | int main() { 54 | int T; 55 | init(); 56 | scanf("%d", &T); 57 | while (T--) 58 | printf("%d\n", solve()); 59 | return 0; 60 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southeastern_Europe/la4190.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Southeastern Europe: GCD Determinant 2 | // ACM-ICPC Live Archive 4190 3 | 4 | #include 5 | #include 6 | #define MM 1000000007 7 | int n; 8 | long long phi(long long n) { 9 | long long phi = n, i, j; 10 | for (i = 2, j = 4; j <= n; i++, j += i + i - 1) 11 | if (!(n % i)) { 12 | phi = phi / i * (i - 1); 13 | while (!(n % i)) 14 | n /= i; 15 | } 16 | if (n > 1) phi = phi / n * (n - 1); 17 | return phi; 18 | } 19 | 20 | void solve() { 21 | long long ans = 1; 22 | while(n--) 23 | { 24 | long long x; 25 | scanf("%lld", &x); 26 | ans *= phi(x); 27 | ans %= MM; 28 | } 29 | printf("%lld\n", ans); 30 | } 31 | int main() { 32 | 33 | while (scanf("%d", &n) != EOF) 34 | solve(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southeastern_Europe/la4191.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Southeastern Europe: Internet Service Providers 2 | // ACM-ICPC Live Archive 4191 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int main() { 9 | freopen("in.txt", "r", stdin); 10 | long long n, c, t, ans, tt, u; 11 | while (scanf("%lld%lld", &n, &c) != EOF) { 12 | if (n == 0 || c == 0) { 13 | printf("0\n"); 14 | continue; 15 | } 16 | tt = c / (2 * n); 17 | tt += 1, ans = tt * (c - tt * n); 18 | t = tt; 19 | tt -= 1; 20 | u = tt * (c - tt * n); 21 | if (u >= ans) ans = u, t = tt; 22 | tt -= 1; 23 | u = tt * (c - tt * n); 24 | if (u >= ans) ans = u, t = tt; 25 | printf("%lld\n", t); 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southwestern_Europe/4302.cpp: -------------------------------------------------------------------------------- 1 | // CII 4302 2 | // 2008 Southwestern Europe: Toll Road 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 200005 9 | int dp[N]; 10 | struct NODE { 11 | int b, v; 12 | NODE() { 13 | } 14 | NODE(int b, int v) : 15 | b(b), v(v) { 16 | } 17 | }; 18 | vector G[N]; 19 | int n, s, ans = 0; 20 | int v[N]; 21 | void dfs1(int x, int d) { 22 | v[x] = d; 23 | for (int i = 0; i < (int) G[x].size(); i++) 24 | if (!v[G[x][i].b]) dfs1(G[x][i].b, d + 1); 25 | } 26 | 27 | void dfs2(int x) { 28 | int i; 29 | dp[x] = 0; 30 | for (i = 0; i < G[x].size(); i++) { 31 | if (v[x] > v[G[x][i].b]) continue; 32 | dfs2(G[x][i].b); 33 | if (dp[G[x][i].b] + G[x][i].v > 0) dp[x] += dp[G[x][i].b] + G[x][i].v; 34 | } 35 | ans = max(ans, dp[x]); 36 | } 37 | void solve() { 38 | s = -1; 39 | memset(G, 0, sizeof(G)); 40 | while (n--) { 41 | int a, b, w; 42 | scanf("%d%d%d", &a, &b, &w); 43 | if (s == -1) s = a; 44 | G[a].push_back(NODE(b, w)); 45 | G[b].push_back(NODE(a, w)); 46 | } 47 | memset(v, 0, sizeof(v)); 48 | dfs1(s, 1); 49 | ans = 0; 50 | dfs2(s); 51 | printf("%d\n", ans); 52 | } 53 | 54 | int main() { 55 | while (scanf("%d", &n) && n) 56 | solve(); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southwestern_Europe/4304.cpp: -------------------------------------------------------------------------------- 1 | // CII 4304 2 | // 2008 Southwestern Europe: Transcribed Books 3 | #include 4 | typedef long long ll; 5 | 6 | ll gcd(ll m, ll n) { 7 | ll r; 8 | while (n > 0) { 9 | r = m % n; 10 | m = n; 11 | n = r; 12 | } 13 | return m; 14 | } 15 | 16 | void solve() { 17 | ll max = 0, x, gc = 0; 18 | int i, j, n; 19 | scanf("%d", &n); 20 | for (i = 0; i < n; i++) { 21 | ll sum = 0; 22 | for (j = 0; j < 9; j++) { 23 | scanf("%lld", &x); 24 | sum += x; 25 | } 26 | scanf("%lld", &x); 27 | if (x > max) max = x; 28 | sum -= x; 29 | if (sum < 0) sum = -sum; 30 | gc = gcd(sum, gc); 31 | } 32 | if (gc <= 1 || gc <= max) printf("impossible\n"); 33 | else printf("%lld\n", gc); 34 | } 35 | int main() { 36 | int T; 37 | scanf("%d", &T); 38 | while (T--) 39 | solve(); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Southwestern_Europe/img/4303_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Southwestern_Europe/img/4303_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Taipei/img/la4263_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.Taipei/img/la4263_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.Taipei/la4262.cpp: -------------------------------------------------------------------------------- 1 | // 2008 Taipei: Road Networks 2 | // ACM-ICPC Live Archive 4262 3 | #include 4 | #include 5 | #include 6 | #define N 1005 7 | struct EDGE { 8 | int b, next; 9 | }; 10 | EDGE ET[700005]; 11 | int GA[N], GD[N], tot, pos[N]; 12 | 13 | inline void addedge(int *g, int s, int t) { 14 | EDGE x = { t, *(g + s) }; 15 | ET[tot] = x; 16 | *(g + s) = tot++; 17 | } 18 | 19 | inline void add(int s, int t) { 20 | addedge(GA, s, t), addedge(GD, t, s); 21 | } 22 | 23 | int color[N], v[N], block[N], pp; 24 | void dfs1(int x) { 25 | v[x] = 1; 26 | for (int i = GA[x]; i != -1; i = ET[i].next) 27 | if (!v[ET[i].b]) dfs1(ET[i].b); 28 | pos[pp++] = x; 29 | } 30 | void dfs2(int x, int id) { 31 | v[x] = 0, block[x] = id; 32 | for (int i = GD[x]; i != -1; i = ET[i].next) 33 | if (v[ET[i].b]) dfs2(ET[i].b, id); 34 | } 35 | void solve() { 36 | int i, nblock = 0, n, m, a, b; 37 | memset(GA, -1, sizeof(GA)); 38 | memset(GD, -1, sizeof(GD)); 39 | tot = 0; 40 | scanf("%d%d", &n, &m); 41 | while (m--) { 42 | scanf("%d%d", &a, &b); 43 | add(a, b); 44 | } 45 | pp = 1; 46 | memset(v, 0, sizeof(v)); 47 | for (i = 1; i <= n; i++) 48 | if (!v[i]) dfs1(i); 49 | for (i = n; i >= 1; i--) 50 | if (v[pos[i]]) dfs2(pos[i], pos[i]), nblock++; 51 | printf("%d\n", nblock); 52 | } 53 | 54 | int main() { 55 | int T, x; 56 | scanf("%d", &T); 57 | while (T--) { 58 | solve(); 59 | scanf("%d", &x); 60 | } 61 | return 0; 62 | } -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4423.cpp: -------------------------------------------------------------------------------- 1 | // CII 4423 2 | // 2008 Tehran: String LD 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 105 8 | char ch[N][N]; 9 | int len[N]; 10 | int getcommon(char *s1, char *s2, int len) { 11 | int ret = 0, i; 12 | for (i = len - 1; i >= 0; i--) { 13 | if (s1[i] != s2[i]) return ret; 14 | ret++; 15 | } 16 | return ret; 17 | } 18 | int n; 19 | void solve() { 20 | int i, j, minlen = 10000; 21 | for (i = 0; i < n; i++) { 22 | scanf("%s", ch[i]); 23 | len[i] = strlen(ch[i]); 24 | minlen = min(minlen, len[i]); 25 | } 26 | for (i = 0; i < n; i++) 27 | for (j = i + 1; j < n; j++) { 28 | if (len[i] != len[j]) continue; 29 | int t = len[i] - getcommon(ch[i], ch[j], len[i]); 30 | minlen = min(t, minlen); 31 | } 32 | printf("%d\n", minlen - 1); 33 | } 34 | int main() { 35 | while (scanf("%d", &n) && n) 36 | solve(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4423_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: String LD 2 | 3 | ## Solution 4 | 5 | 易得,要满足第二个停止条件,那么出现相等的两个原长度必定相等。因此两两枚举字符串,如果长度相等,则求出len-尾部算起的公共子串长度-1。这就是第二个条件所取得时的最小值。 6 | 7 | 第一个条件取得的最小值是最短的字符串的长度-1。 8 | 9 | 比较两个最小值,取小者即得答案。 10 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4424_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: Painting 2 | ## Solution 3 | 4 | 可以使用类似拓扑排序的方法处理这个问题。对于每种颜色,有三种可能:可以判断横放,可以判断竖放,不可判断。之后不断选出一个在最上面颜色,删去(也就是设置为0)。判断最上面的要求是:该颜色在该行的数目,加上已经被删去(也就是0)的方格,等于列的数目;或该颜色在该列的数目,加上已经被删去(也就是0)的方格,等于行的数目。 5 | 6 | 注意字典序的处理。因为我们是逆序得到答案的。因此要逆序得到字典序最大,才能得到正序的字典序最小。 7 | 8 | #### Thanks 9 | alpc23 10 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4425_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: Another Brick in the Wall 2 | 3 | ## Solution 4 | 5 | 1. 预处理出所有砖头,给这些砖头加上编号 6 | 2. 建立正向和反向的拓扑关系图。如果砖头A的取出能够导致砖头B的坍塌,那么正向图中A到B有连边。如果砖头B的坍塌依赖于砖头A,那么反向图中B到A有连边。一个砖头的坍塌有可能依赖于多个砖头。明显,我们建出来的拓扑关系图是有层次的。 7 | 3. 枚举每个砖头,对正向图进行BFS,对于访问过的砖头,如果其会坍塌,则标记其为visit。每次访问一个砖头x,要知道其是否会坍塌,只需要遍历反向图中x的儿子,看看这些儿子是不是全部是visit即可。 8 | 9 | 一个小小的常数优化:只有正向图中入度不为1的砖头,才对其进行BFS。因为入度为1的砖头,明显拆其父亲节点的砖头能够造成更大的损害。 10 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4426.cpp: -------------------------------------------------------------------------------- 1 | // CII 4426 2 | // 2008 Tehran: Blast the Enemy! 3 | #include 4 | #include 5 | #define EPS 1e-8 6 | #define N 105 7 | struct POINT { 8 | double x, y; 9 | POINT() { 10 | x = y = 0; 11 | } 12 | POINT(double x, double y) : 13 | x(x), y(y) { 14 | } 15 | void get() { 16 | scanf("%lf%lf", &x, &y); 17 | } 18 | void print() { 19 | printf("%.6lf %.6lf\n", x, y); 20 | } 21 | POINT operator+(const POINT &p) { 22 | return POINT(x + p.x, y + p.y); 23 | } 24 | }; 25 | POINT pl[N]; 26 | int n; 27 | double cross(POINT o, POINT &a, POINT &b) { 28 | return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x); 29 | } 30 | int sgn(double x) { 31 | return x < -EPS ? -1 : x > EPS; 32 | } 33 | void solve() { 34 | int i; 35 | double area = 0; 36 | POINT ct; 37 | for (i = 0; i < n; i++) 38 | pl[i].get(); 39 | pl[i] = pl[0]; 40 | for (i = 0; i < n; i++) { 41 | double s = cross(POINT(), pl[i], pl[i + 1]); 42 | POINT t; 43 | area += s; 44 | t = pl[i] + pl[i + 1]; 45 | ct.x += s * t.x, ct.y += s * t.y; 46 | } 47 | ct.x = ct.x / area / 3.0, ct.y = ct.y / area / 3.0; 48 | ct.print(); 49 | } 50 | int main() { 51 | int T = 1; 52 | while (scanf("%d", &n) && n) { 53 | printf("Stage #%d: ", T++); 54 | solve(); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4426_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: Blast the Enemy! 2 | ## Summary 3 | 4 | 给出一个有n(n<=100)个点的简单多边形,求该多边形的重心。 5 | ## Solution 6 | 7 | 根据多边形重心的定义,可以对其进行三角剖分,计算每个三角形的面积以及重心。多边形的重心就是所有三角形的重心对面积的加权平均数,也就是说: 8 |
 9 | center.x = (cen[0].x * area[0] + cen[1].x * area[1] ..... + cen[n].x * area[n]) / totalarea
10 | center.y = (cen[0].y * area[0] + cen[1].y * area[1] ..... + cen[n].y * area[n]) / totalarea
11 | 
12 | cen[i]代表第i个三角形的重心,三角形的重心就是: 13 | 14 |
15 | center_of_tri.x=(p1.x+p2.x+p3.x)/3.0
16 | center_of_tri.y=(p1.y+p2.y+p3.y)/3.0
17 | 
18 | area[i]就是第i个三角形的面积。totalarea就是多边形的总面积。 19 | 20 | 三角剖分的技巧是:三角形的一个点是原点,然后枚举多边形的另外两个相邻的点,构成三角形。所有的面积均为有向面积,这样可以无论点是顺时 针还是逆时针给出,都无需特殊处理,且运算简单。 21 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4427_Solution.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: deltree 2 | ## Solution 3 | Read the problem carefully and do the simulation according to the description. 4 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4428_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran Solar Eclipse Solution 2 | ## Summary 3 | 4 | 给出N个圆(N<=100),半径均为R,这些圆有可能重合。现要求在平面上放置一个圆,与给出的圆不重叠(但可以相切),使这个圆距离原点最近。要求给出最小的距离值。 5 | ## Solution 6 | 7 | 易得最优的方案,放置的圆必定与原来的圆相切。因此将原来给出的N个圆的半径都放大为2R,那么问题就转化为,在平面上找一个点,不在所给的圆内,且离原点最近。对于这个问题要分两种情况讨论: 8 | 9 | 1. 原点没有被覆盖,那么明显原点就是要找的点。 10 | 2. 原点被覆盖了,那么这个点必定在所给的圆相交形成的形状的轮廓上。这些轮廓必定是由一段段圆弧组成的。我们只要把这些圆弧处理出来,求出所有圆弧离原点最近的一点,即是答案。 11 | 12 | 圆弧到原点的最近距离可以这样求: 13 | 14 | 1. 弧对应的圆的圆心P与原点O的连线为PO,如果PO经过圆弧,那么PO与弧的交点就是所求。(注意方向是PO)。 15 | 16 | 2. 否则,弧离原点最近的点必定在弧的其中一个端点上。枚举一下可得答案。 17 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4429.cpp: -------------------------------------------------------------------------------- 1 | // CII 4429 2 | // 2008 Tehran: Hurry Plotter 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 1005 8 | 9 | int n, t; 10 | struct SEG { 11 | int y, x1, x2; 12 | bool operator <(const SEG &s) const { 13 | if (y != s.y) return y < s.y; 14 | return x1 < s.x1; 15 | } 16 | void get() { 17 | scanf("%d%d%d", &y, &x1, &x2); 18 | } 19 | }; 20 | SEG sl[N]; 21 | int dp[N][N]; 22 | int dis(SEG &a, SEG &b) { 23 | if (a.y == b.y) return b.x1 - a.x2; 24 | return a.x2 + b.x1; 25 | } 26 | 27 | void solve() { 28 | int i, j, k, best = 0; 29 | for (i = 1; i <= n; i++) 30 | sl[i].get(); 31 | sort(sl + 1, sl + n + 1); 32 | for (i = 1; i <= n; i++) 33 | dp[i][1] = sl[i].x2 - sl[i].x1 + sl[i].x2; 34 | for (i = 1; i <= n; i++) 35 | for (j = 2; j <= i; j++) { 36 | dp[i][j] = 1 << 30; 37 | for (k = j - 1; k < i; k++) 38 | dp[i][j] = min(dp[i][j], dp[k][j - 1] + dis(sl[k], sl[i])); 39 | dp[i][j] += (sl[i].x2 - sl[i].x1) * 2; 40 | } 41 | 42 | for (i = 1; i <= n; i++) 43 | for (j = 1; j <= i; j++) 44 | if (dp[i][j] <= t) best = max(j, best); 45 | printf("%d\n", best); 46 | } 47 | int main() { 48 | while (scanf("%d%d", &n, &t) && n + t) 49 | solve(); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4429_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: Hurry Plotter 2 | ## Summary 3 | 4 | 给出N(N<=1000)个需要绘制的平行于X轴的线段,知道其坐标,以(Y,X1,X2)表示。有一绘图仪,从Y=0位置开始绘制这些线段。对于同一个Y,绘图仪可以从X=x1到X=x2,平移时耗费时间|x2-x1|,绘制线段则耗费双倍时间2|x2-x1|。但是,在垂直方向上,绘图仪只能从y1移动到y2,y1=m且自己的票数最多,是很难解决的。因此这个问题需要转换一个角度来考虑。在其它政党获得的主席、副主席、秘书的数目确定的情况下,我们当然希望别人的席位越多越好,以弥补自己缺失的席位。因此问题可以转换成:其它政党获得a个主席,b个副主席,c个秘书的情况下,最多能有多少个席位。这样就是一个分组背包问题,可以使用DP解决。 7 | 8 | DP的状态为DP[i][a][b][c],表示选择到第i个政党时,这些政党获得a个主席,b个副主席,c个秘书的情况下能够占有的最多的席位。DP转移见程序。DP后将整个数组扫一次,那么就可以得到答案。 9 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.Tehran/4431_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 Tehran: Fruit Weights 2 | ## Summary 3 | 4 | 有N种水果,现知道许多以下的关系: 5 | 6 | aX<=bY 7 | 8 | 表示:a个X水果的重量小于b个水果Y的重量。给出许多这些小于关系后,最后问a个X水果和b个Y水果的重量关系。水果的数目不超过一百。 9 | 10 | ## Solution 11 | 12 | 这个问题可以转化成图论问题考虑。视每个水果为一个节点,对于关系aX<=bY,我们可以建立一条从Y到X的边,权值为a/b,意思是Y水果 的单位重量至少是X水果的a/b倍。 13 | 14 | 然后使用floyd算法求一次最短路,将加法改成乘法即可。算出每种水果之间的重量比例关系。 15 | 16 | 检查算出来的矩阵,如果有g[i][i]>1,那么就是出现矛盾,判为INCONSISTENT。 17 | 18 | 如果要判定aX是否<=bY,也就是判定Y>=(a/b)X。对于算出的矩阵,g[Y][X]表示Y>=g[Y] [X]X。若判定Y>=(a/b)X成立,必有(a/b)<=G[Y][X]。 19 | 20 | 对于相等的情况特判一下即可。 21 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4118_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 World Finals: Air Conditioning Machinery 2 | 3 | ## Solution 4 | 可以使用限制深度的迭代加深方法进行DFS。使用四元组(x,y,z,dir)表示当前的状态即可。 5 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4123.cpp: -------------------------------------------------------------------------------- 1 | // CII 4123 2 | // 2008 World Finals: Glenbow Museum 3 | #include 4 | #include 5 | long long f(long long x) { 6 | return x * (x - 1) * (x - 2) * (x - 3) / 4 / 3 / 2; 7 | } 8 | int main() { 9 | long long n, ans; 10 | int ca = 1; 11 | while (scanf("%lld", &n) && n) { 12 | if (n % 2) ans = 0; 13 | else { 14 | n = (n + 4) / 2; 15 | ans = f(n) + f(n - 1); 16 | } 17 | printf("Case %d: %lld\n", ca++, ans); 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4123_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.World_Finals/4123_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4123_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 World Finals: Glenbow Museum 2 | 3 | 一个合法的字符串有如下性质 4 | 5 | * 由于多边形外角和是360度,每个R为外角和“贡献”90度,每个O为外角和贡献-90度。所以R肯定比O多四个。 6 | * 不可能存在两个相邻的O。原因:如果有两个相邻的O,那么必定不能形成星形多边形。如图,有两个连续的O,看到R1点的区域位于R1O1的左边(紫色区域),看到R2点的区域位于R2OR的右边(绿色区域),两个区域没有重叠,因此不满足题目要求。 7 | 8 | ![Alt text](4123_Img1.jpg "Image 1") 9 | 10 | 那么问题就转化为:给出r个R,r-4个O,求这些R与O能够组成多少种字符串,使得没有两个O相邻。这时有如下两种情况: 11 | 12 | 1. 串长为奇数则答案为0。 13 | 2. 字符串以R结尾,那么如果有r个R,那么相当于找4个位置放多出来的四个R,其余放OR。方案数为C(r,4)。 14 | 3. 字符串以O结尾,那么如果有r个R,字符串的形式必定是xxxxxxRO(因为最后的那个O前面必定是R)。那么相当于找在r-1个位置中找4个放R,其余位置放RO。方案数为C(r-1,4)。 15 | 16 | 最终答案就是C(r,4)+C(r-1,4)。 17 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4125_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2008.World_Finals/4125_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4125_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 World Finals: Painter 2 | ## Summary 3 | 4 | 给定平面上的N个三角形(N<=100000),判断是否有任意两个相交,如果没有,给出嵌套的最大层数。 5 | 6 | ## Solution 7 | 8 | 如果不相交,那么可以使用扫描线算法解决。 9 | 10 | 扫描线x=K从左向右扫描平面上所有的三角形,假设三角形三个点按照从左向右为p1,p2,p3,会发生如下事件点: 11 | 12 | 1. 插入事件,插入一个新的三角形的两条边(p1,p2),(p1,p3)。 13 | 2. 变更事件,删除三角形的一条边(p1,p2),插入(p2,p3) 14 | 3. 删除事件,退出整个三角形(p1,p3),(p2,p3)。 15 | 16 | ![Alt text](4125_Img1.jpg "Image 1") 17 | 18 | 19 | 括号表示法:如图,用括号序列表示扫描线事件点发生后,三角形的边的在y方向的嵌套关系。图中红色表示插入事件,黄色表示变更事件,蓝色表示删除事件。 20 |
21 | 1 ()
22 | 2 (()) 
23 | 3 (()())
24 | 4 (()())
25 | 5 ((())())
26 | 6 ((())())
27 | 7 (()())
28 | 8 (()())
29 | 9 (())
30 | A ()
31 | B (())
32 | C (())
33 | D ()
34 | E 
35 | 
36 | 这个括号序列,也就是许多线段,可以使用平衡二叉树来维护,线段之间的大小关系就是该线段在当前扫描线时的y坐标。虽然每个括号在不同扫描线x=K的时候,y坐标都不一样,但是如果不发生线段相交的话,其位置关系是不变的。 37 | 38 | 根据扫描线算法的定义,有如下规律: 39 | 40 | * 线段的相交只会发生在平衡树上“相邻”的两个节点中。因此只需要在插入后检查当前插入线段是否去相邻两个节点相交,删除前判断删除的线段的前后两个将要变成相邻节点的两个线段是否相交,即可判断出是否有三角形相交。 41 | * 嵌套层数,使用depth表示,为平衡树的字段: 42 |
43 | if x 为左括号 then x=pre(x).depth+1
44 | else if x 为右括号 then x=pre(x).depth-1
45 | pre为前一个节点。
46 | 
47 | 48 | 实现细节 49 | 50 | * 实现时为了不把来自同一个三角形的线段误作相交,需要在线段中记录来自哪个三角形。 51 | * 扫描线的事件点,实际上是发生在点坐标x的偏右一点点的位置,才会产生两条线段。因此每次检查x时,先对x加上一个很小的数值eps,再计算出扫描线割该线段时对应的y坐标。 52 | * 如果线段垂直与X轴,那么直接计算y坐标会出错。这时可以把线段中点的y坐标作为扫描线割该线段对应的y值。 53 | * 平衡树可以使用multimap来实现,如果迭代器为it,那么it的前一个点就是it--,后一个点就是it++。 54 | 55 | ##### Thanks 56 | Zhang Kunwei 57 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4127_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 World Finals The Sky is the Limit 2 | 3 | ## Solution 4 | 5 | 由于n的范围比较小,n<=100,因此可以想到如下比较容易想到的方法: 6 | 7 | 首先把根据每个山峰的起点,中点,终点,以及各个山峰之间的交点,所有的这些点的x坐标,数轴划分成很多个区间。那么,易得数轴上每个区间,山的轮廓线不会交叉。那么我们只要找出区间上面最“高”的那条线段就是所求。求出这些最高的线段后,将其长度累计即可。 8 | -------------------------------------------------------------------------------- /ICPC.Regional/2008.World_Finals/4128_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2008 World Finals: Steam Roller 2 | 3 | 使用最短路算法解决该问题。 4 | 5 | 由于刹车前后的道路,以及启动后、终止前的道路的耗费的时间都要加倍,因此需要有恰当的状态表示方法,以免某些道路的加倍被重复计算。最短 路使用状态:dis[issame][direction][pt]表示,意思是当前点为Pt,进入pt的方向为dir,前两条步的方向是否相同为 issame的情况下,到达pt前一点pp的最短路。之所以这样表示状态,是因为pp是否按双倍计算是不知道的。选择当前点的前进方向,会影响之前的时间 (如果转弯,上一段路的时间就要加倍)。如果不加以记录,有可能会重复计算。对于当前的状态,如果issame为false,或当前dir与下一个dir 不一致,都要将pp到pt这一段路的距离双倍计算。 6 | 7 | 注意起始点与终点的处理。尤其是到达终点,必须进行统计最优值,而不能马上退出。而且到达终点后有可能继续走,再返回终点,会得到更优的答案,要稍加注意。 8 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4676_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Geometry Problem 2 | 3 | ## Summary 4 | 5 | 给出两个三角形,知道其顶点位置以及在x,y方向的速度,问这两个三角形是否会发生碰撞。如果碰撞,则输出发生碰撞的时间。 6 | 7 | ## Solution 8 | 9 | 对于三角形A和B,使用相对运动的思维,假设A动B不动,那么可以算出A的相对B的运动速度。枚举A的三个顶点,计算该顶点是否会碰撞到B的某条边,这就是一个射线与线段相交的问题。如果碰撞,则计算出碰撞的时间t。 10 | 11 | 题目给出三角形t1和t2,那么假设t1不动t2动,使用上面的方法算一次,假设t2不动,t1动,再算一次,所有的碰撞时间的最小值就是 所求。 12 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4677.cpp: -------------------------------------------------------------------------------- 1 | // CII 4677 2 | // 2009 Amritapuri: Interleaved Periodic String 3 | #include 4 | #include 5 | 6 | char s[100]; 7 | void solve() { 8 | scanf("%s", s); 9 | int len = strlen(s); 10 | int ans = 1, i; 11 | for (i = 1; i < len; i++) 12 | if (s[i] != s[0]) ans = 2; 13 | printf("%d\n", ans); 14 | } 15 | int main() { 16 | int T; 17 | scanf("%d", &T); 18 | while (T--) 19 | solve(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4677_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Interleaved Periodic String 2 | 3 | ## Solution 4 | 5 | 题目说得很复杂,实际上就是:因为每个串无论如何组成,都可以由000..和111...交叉构成。而000...,111...都可以由一个0或 一个1倍增得到。因此如果字符串所有字符相同,就输出1,否则输出2即可。 6 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4680.cpp: -------------------------------------------------------------------------------- 1 | // CII 4680 2 | // 2009 Amritapuri: Trip Compulsion 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 3005 8 | #define INF 2000000011 9 | struct EDGE { 10 | int a, b, x; 11 | void get() { 12 | scanf("%d%d%d", &a, &b, &x); 13 | } 14 | bool operator <(const EDGE &e) const { 15 | return x < e.x; 16 | } 17 | }; 18 | int n, m, fa[N]; 19 | EDGE e[N]; 20 | void init() { 21 | for (int i = 0; i < n; i++) 22 | fa[i] = i; 23 | } 24 | int find(int x) { 25 | if (fa[x] != x) fa[x] = find(fa[x]); 26 | return fa[x]; 27 | } 28 | void solve() { 29 | int s, t, i, j, ans = INF; 30 | scanf("%d%d", &n, &m); 31 | scanf("%d%d", &s, &t); 32 | for (i = 0; i < m; i++) 33 | e[i].get(); 34 | sort(e, e + m); 35 | for (i = 0; i < m; i++) { 36 | init(); 37 | for (j = i; j < m && find(s) != find(t); j++) 38 | fa[find(e[j].a)] = find(e[j].b); 39 | if (find(s) == find(t)) ans = min(e[j-1].x - e[i].x, ans); 40 | } 41 | if (ans == INF) printf("NO PATH\n"); 42 | else printf("%d\n", ans); 43 | } 44 | int main() { 45 | int T; 46 | scanf("%d", &T); 47 | while (T--) 48 | solve(); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4680_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Trip Compulsion 2 | ## Summary 3 | 4 | 给出一个无向图(顶点数n<=2000,边数m<=3000),求从s到t的一条路,使该路上最长的边与最短的边的差值最小。 5 | ## Solution 6 | 7 | 使用枚举+贪心的算法解决。 8 | 9 | 先对题目给出的边进行排序。然后枚举从s到t的路上的最短边E1,然后该最短边到大把图中的边逐条加入,直至s与t联通为止。那么最后加入 的这条边E2就必定是在最短边为E1的情况下,长度最短的最长边。求出差值,更新答案即可。 10 | 11 | 判断s与t是否联通,可以使用并查集把每次加入的新边的两个顶点连起来即可。 12 | 13 | 该算法总复杂度为O(m2)。 14 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4681_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Visible Lattice 2 | 3 | ## Summary 4 | 定理题。给出坐标值(x,y,z),取出其中不为0的值,求GCD。如果GCD=1,该点可见,否则说明(0,0,0)-(x,y,z)之间必定有 其他点遮挡实现,因而不可见 5 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4682.cpp: -------------------------------------------------------------------------------- 1 | // CII 4682 2 | // 2009 Amritapuri: XOR Sum 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 100005 8 | 9 | unsigned int a[N], xs[N]; 10 | 11 | int son[29 * N][2]; 12 | int tot = 1; 13 | void insert(int x) { 14 | int i, next, cur = 1; 15 | for (i = 31; i >= 0; i--) { 16 | unsigned int m = (1 << i); 17 | next = (x & m) > 0; 18 | if (son[cur][next] == -1) son[cur][next] = ++tot; 19 | cur = son[cur][next]; 20 | } 21 | } 22 | 23 | int ans; 24 | void find(int x) { 25 | int i, cur = 1, opp = 0; 26 | for (i = 31; i >= 0; i--) { 27 | unsigned int m = (1 << i); 28 | int next = (x & m) > 0; 29 | if (son[cur][!next] != -1) { 30 | cur = son[cur][!next]; 31 | if (!next) opp = opp | m; 32 | } else { 33 | cur = son[cur][next]; 34 | if (next) opp = opp | m; 35 | } 36 | } 37 | ans = max(ans, opp ^ x); 38 | } 39 | void solve() { 40 | int n, i; 41 | scanf("%d", &n); 42 | for (i = 1; i <= n; i++) { 43 | scanf("%d", &a[i]); 44 | } 45 | xs[0] = 0; 46 | tot = 1; 47 | memset(son, -1, sizeof(son)); 48 | for (i = 1; i <= n; i++) { 49 | xs[i] = xs[i - 1] ^ a[i]; 50 | insert(xs[i]); 51 | } 52 | ans = 0; 53 | for (i = 0; i <= n; i++) 54 | find(xs[i]); 55 | printf("%d\n", ans); 56 | } 57 | int main() { 58 | int T; 59 | scanf("%d", &T); 60 | while (T--) 61 | solve(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4682_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: XOR Sum 2 | 3 | ## Summary 4 | 5 | 给出N个数字(N<=100000)。求一个连续的区间,使这些区间的数字的异或和最大。 6 | ## Solution 7 | 8 | 异或运算有一个很基础的性质:a^(a^b)=b。因此,设q[i]为1-i区间中所有的数的异或值,那么[x,y]区间所有数字的异或值就是 q[x-1]^q[y],也就是说,预处理出q数组后,问题就转化为在N个数字中,找出两个数字,使其异或值最大。 9 | 10 | 由于N很大(N<=100000),因此不能够直接使用O(n2)的算法。考虑到异或运算的定义:二进制中某 一位相同则0,不同则1。那么我们得到的贪心策略是:越往高的位,尽量希望他能够是1。因此,可以考虑用一个类似Trie树的数据结构把所有的数字的二进 制从高位到低位保存起来。然后再枚举每个数字x,如果x的当前位是1,那么就看看Trie树中当前位是否存在为0的分支,有则往0分支走,否则才往1的分 支走。反之,如果x的当前位是0,那么就看看Trie树总是否存在1的分支,有则往1的分支走,否则才往0的分支走。这样从高位到低位贪心取不同位,能够 保证高位尽量为1,那么得出来的两个数字的异或值肯定最大。 11 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4683_Solution.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Find The Number 2 | 3 | ## Solution 4 | Use inclusion–exclusion principle to resolve it. 5 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4684_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Love for Pizza 2 | 3 | ## Solution 4 | 5 | 题目分两步。第一步就是把所有的点按照角度排序,然后把相同角度的toppings的值合并(因为一刀切下去的时候,相同角度的topping肯定 位于同一块之中)。 6 | 7 | 第二步就是一个圆周上的最大子段和模型。由于处理圆周问题比较麻烦,因此可以把圆拆开,复制两次,转换成一个序列的,保存为 seq[n*2]。设f(x,y)为普通序列上,[x,y]区间的最大字段和,那么圆周的最大字段和相当于max(f(i,i+n-1)), i = 1 to n。多次询问一个数组的最大子段和可以使用线段树解决。因此使用线段树预处理序列seq[1..2n]后,f(x,y)函数在log(n)时间内查询出所 有的[i,i+n-1]区间的最大子段和。 8 | 9 | 线段树的解决方法是:线段树节点存储当前区间总和, 当前区间左边连续的最大值, 中间连续的最大值, 右边连续的最大值这四个字段。 10 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Amritapuri/4685_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 Amritapuri: Succession 2 | 3 | ## Summary 4 | 5 | 给出一棵节点带权的树,节点数不大于100.要求出一个连通的节点集合,使其权值和最大,且节点数恰好为K.要求输出达到最优值时的方案数。 6 | ## Solution 7 | 8 | O(n3)的树型DP. 使用dp[x][k]来表示以k为根节点的树,使用k个节点,能够最大达到的权值. 9 | 10 | 易得:dp[x][k] = max(dp[i][l] + dp[x][k-l]).l从0遍历到k-1. 这是因为子树可以一个点也不取,但是不能全取. 因为要求的是一棵树, 子树的节点最多取k-1个,留一个给当前的根. 11 | 12 | 遍历k,从K到2,即可得到当前点的所有状态值.(类似背包问题). 13 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Dhaka/4493.cpp: -------------------------------------------------------------------------------- 1 | // CII 4493 2 | // 2009 Dhaka: That is Your Queue 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | int Q[5000]; 8 | int main() { 9 | int ca = 1, n, q, x; 10 | char cmd[3]; 11 | while (scanf("%d%d", &n, &q) && n + q) { 12 | printf("Case %d:\n", ca++); 13 | int qh = 2000, qe = 2000, i; 14 | for (i = 1; i <= min(1000, n); i++) 15 | Q[qe++] = i; 16 | while (q--) { 17 | scanf("%s", cmd); 18 | if (cmd[0] == 'N') { 19 | while (1) { 20 | x = Q[qh++]; 21 | if (x != -1) break; 22 | } 23 | Q[qe++] = x; 24 | printf("%d\n", x); 25 | } else { 26 | scanf("%d", &x); 27 | for (i = qh; i < qe; i++) 28 | if (Q[i] == x) { 29 | Q[i] = -1; 30 | break; 31 | } 32 | Q[--qh] = x; 33 | } 34 | } 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Dhaka/4494.cpp: -------------------------------------------------------------------------------- 1 | // CII 4494 2 | // 2009 Dhaka: How Many Ones Needed? 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | long long a, b; 8 | long long dp[50]; 9 | long long bin(long long x) { 10 | long long i, ans; 11 | for (i = 1;; i++) { 12 | if ((1LL << i) <= x) ans = i; 13 | else break; 14 | } 15 | return ans; 16 | } 17 | long long f(long long x) { 18 | if (x == 0) return 0; 19 | if (x == 1) return 1; 20 | long long b = bin(x); 21 | long long u = (1LL << b); 22 | return dp[b] + f(x - u) + x - u + 1; 23 | } 24 | long long solve() { 25 | if (a <= 1) return f(b); 26 | return f(b) - f(a - 1); 27 | } 28 | int main() { 29 | int ca = 1, i; 30 | long long t = 2; 31 | dp[0] = 0, dp[1] = 1; 32 | for (i = 2; i <= 32; i++) { 33 | dp[i] = dp[i - 1] * 2LL + t; 34 | t <<= 1LL; 35 | } 36 | while (scanf("%lld%lld", &a, &b) && a + b) 37 | printf("Case %d: %lld\n", ca++, solve()); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Dhaka/4496.cpp: -------------------------------------------------------------------------------- 1 | // CII 4496 2 | // 2009 Dhaka: A Match Making Problem 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | int main() { 8 | int ca = 1, B, H; 9 | while (scanf("%d%d", &B, &H) && B + H) { 10 | int x, mm = 10000, i; 11 | for (i = 0; i < B; i++) { 12 | scanf("%d", &x); 13 | mm = min(mm, x); 14 | } 15 | for (i = 0; i < H; i++) 16 | scanf("%d", &x); 17 | printf("Case %d: %d", ca++, max(B - H, 0)); 18 | if (max(B - H, 0)) printf(" %d", mm); 19 | printf("\n"); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Dhaka/img/4500_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2009.Dhaka/img/4500_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2009.Harbin/la4764.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Harbin: Bing it 2 | // ACM-ICPC Live Archive 4764 3 | #include 4 | #include 5 | #define N 100005 6 | int last[N], n; 7 | int solve(){ 8 | int best = 0, card; 9 | memset(last, -1, sizeof(last)); 10 | for (int i = 0; i < n; i++){ 11 | scanf("%d", &card); 12 | if (last[card] != -1){ 13 | int score = last[card] + (card == 999 ? 3 : 1); 14 | if (score > best) 15 | best = score; 16 | } 17 | last[card] = best; 18 | } 19 | return best; 20 | } 21 | 22 | int main(){ 23 | while (scanf("%d", &n) && n) 24 | printf("%d\n", solve()); 25 | } -------------------------------------------------------------------------------- /ICPC.Regional/2009.Harbin/la4773.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Harbin: YY and YY Again 2 | // ACM-ICPC Live Archive 4773 3 | #include 4 | #include 5 | char s[1000]; 6 | int main() { 7 | while (gets(s)) { 8 | int len, i, ans = 0; 9 | len = strlen(s); 10 | for(i=0;i= 'A') ans += s[i] - 'A' + 1; 12 | if(ans <= 100)printf("%d\n",ans); 13 | else printf("INVALID\n"); 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Hefei/4667.cpp: -------------------------------------------------------------------------------- 1 | // CII 4667 2 | // 2009 Hefei: Mersenne Prime 3 | #include 4 | 5 | int main() { 6 | bool is[258] = { 0 }; 7 | is[2] = 1, is[3] = 1, is[5] = 1, is[7] = 1, is[13] = 1; 8 | is[17] = 1, is[19] = 1, is[31] = 1, is[61] = 1, is[89] = 1; 9 | is[107] = 1, is[127] = 1; 10 | int x; 11 | while (scanf("%d", &x) && x) 12 | printf(is[x] ? "%d:Prime\n" : "%d:NotPrime\n", x); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Hefei/4669.cpp: -------------------------------------------------------------------------------- 1 | // CII 4669 2 | // 2009 Hefei: Laser in Cuboids 3 | #include 4 | 5 | int gcd(int m, int n) { 6 | int r; 7 | while (n > 0) { 8 | r = m % n; 9 | m = n; 10 | n = r; 11 | } 12 | return m; 13 | } 14 | int main() { 15 | int a, b, c; 16 | while (scanf("%d%d%d", &a, &b, &c) && a + b + c) 17 | printf("%d\n", a + b + c - gcd(a, b) - gcd(b, c) - gcd(a, c) + gcd(c, 18 | gcd(a, b))); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Hefei/4670.cpp: -------------------------------------------------------------------------------- 1 | // CII 4670 - Brute-force solution 2 | // 2009 Hefei: Dominating Patterns 3 | #include 4 | #include 5 | #define LEN 1000005 6 | #define N 155 7 | int P[N]; 8 | char A[LEN], B[N][N]; 9 | int ans[N], len; 10 | void match(int idx) { 11 | int i, j, m, n = len, ans = 0; 12 | P[1] = 0, j = 0; 13 | m = strlen(B[idx] + 1); 14 | 15 | for (i = 2; i <= m; i++) { 16 | while ((j > 0) && (B[idx][j + 1] != B[idx][i])) 17 | j = P[j]; 18 | if (B[idx][j + 1] == B[idx][i]) 19 | j++; 20 | P[i] = j; 21 | } 22 | 23 | j = 0; 24 | for (i = 1; i <= n; i++) { 25 | while (j > 0 && B[idx][j + 1] != A[i]) 26 | j = P[j]; 27 | if (B[idx][j + 1] == A[i]) 28 | j++; 29 | if (j == m) 30 | ans++, j = P[j]; 31 | } 32 | ::ans[idx] = ans; 33 | } 34 | int main() { 35 | int n, i; 36 | while (scanf("%d", &n) && n) { 37 | int best = 0; 38 | for (i = 0; i < n; i++) 39 | scanf("%s", B[i] + 1); 40 | scanf("%s", A + 1); 41 | len = strlen(A + 1); 42 | for (i = 0; i < n; i++) { 43 | match(i); 44 | if (ans[i] > best) 45 | best = ans[i]; 46 | } 47 | printf("%d\n", best); 48 | for (i = 0; i < n; i++) 49 | if (ans[i] == best) 50 | printf("%s\n", B[i] + 1); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Northwestern_Europe/img/4617_Img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2009.Northwestern_Europe/img/4617_Img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2009.Northwestern_Europe/la4611.cpp: -------------------------------------------------------------------------------- 1 | // CII 4611 2 | // 2009 Northwestern Europe: Divisible Subsequences 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 50005 9 | 10 | map MAP; 11 | void solve() { 12 | int n, d, x, s = 0, i; 13 | long long ans = 0; 14 | scanf("%lld%d", &d, &n); 15 | MAP.clear(); 16 | MAP[0] = 1; 17 | for (i = 0; i < n; i++) { 18 | scanf("%d", &x); 19 | s = (s + x) % d; 20 | if (MAP.find(s) != MAP.end()) MAP[s]++; 21 | else MAP[s] = 1; 22 | } 23 | map::iterator it; 24 | for (it = MAP.begin(); it != MAP.end(); it++) { 25 | long long x = it->second - 1; 26 | ans += (x * x + x) / 2; 27 | } 28 | printf("%lld\n", ans); 29 | } 30 | int main() { 31 | int T; 32 | scanf("%d", &T); 33 | while (T--) 34 | solve(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Northwestern_Europe/la4617.cpp: -------------------------------------------------------------------------------- 1 | // CII 4617 2 | // 2009 Northwestern Europe: Simple Polygon 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 2005 8 | struct POINT { 9 | double x, y; 10 | int id; 11 | void get(int i) { 12 | scanf("%lf%lf", &x, &y); 13 | id = i; 14 | } 15 | bool operator <(const POINT &p) const { 16 | if (x != p.x) return x < p.x; 17 | return y < p.y; 18 | } 19 | }; 20 | 21 | inline double cross(const POINT &o, const POINT &a, const POINT &b) { 22 | return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x); 23 | } 24 | 25 | POINT pl[N], ch[N]; 26 | bool vis[N]; 27 | int n; 28 | void solve() { 29 | int n, i, top; 30 | scanf("%d", &n); 31 | for (i = 0; i < n; i++) 32 | pl[i].get(i); 33 | sort(pl, pl + n); 34 | ch[0] = pl[0]; 35 | top = 0; 36 | for (int i = 1; i < n; i++) { 37 | while (top >= 1 && cross(ch[top - 1], pl[i], ch[top]) > 0) 38 | --top; 39 | ch[++top] = pl[i]; 40 | } 41 | memset(vis, 0, sizeof(vis)); 42 | for (i = 0; i <= top; i++) { 43 | printf("%d ", ch[i].id); 44 | vis[ch[i].id] = 1; 45 | } 46 | for (i = n - 1; i >= 0; i--) 47 | if (!vis[pl[i].id]) printf("%d ", pl[i].id); 48 | printf("\n"); 49 | } 50 | int main() { 51 | int T; 52 | scanf("%d", &T); 53 | while (T--) 54 | solve(); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Phuket/img/la4714_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2009.Phuket/img/la4714_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2009.Phuket/img/la4714_img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2009.Phuket/img/la4714_img2.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2009.Phuket/la4713.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Phuket: Elias Omega Coding 2 | // ACM-ICPC Live Archive 4713 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | typedef long long ll; 11 | 12 | int getbit(ll x) 13 | { 14 | int ans = 0; 15 | while(x) 16 | ans++, x >>= 1; 17 | return ans; 18 | } 19 | void f(ll x) 20 | { 21 | if(x == 1) 22 | { 23 | printf("0"); 24 | return; 25 | } 26 | ll bit = getbit(x); 27 | f(bit - 1); 28 | for(ll i = bit-1;i>=0;i--) 29 | { 30 | if(x & (1LL< 4 | #include 5 | double sqr(double x) { 6 | return x * x; 7 | } 8 | double get(double R, double r) { 9 | double x, y; 10 | x = sqrt(sqr((R + r) / 2.0) - sqr((R - r) / 2.0)); 11 | x *= 2; 12 | y = x * r / (R - r); 13 | return x + y; 14 | } 15 | int main() { 16 | double r1, r2, r3, R; 17 | int ca = 1; 18 | while (scanf("%lf%lf%lf%lf", &R, &r1, &r2, &r3) && R > 0) { 19 | double a = get(R, r1); 20 | double b = get(R, r2); 21 | double c = get(R, r3); 22 | double A = a + b, B = a + c, C = b + c; 23 | double p = a+b+c; 24 | double S = sqrt(p * (p - A) * (p - B) * (p - C)); 25 | printf("Case %d: %.2lf\n", ca++, S); 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ICPC.Regional/2009.Phuket/la4716.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Phuket: Relational Operators 2 | // ACM-ICPC Live Archive 4716 3 | #include 4 | #include 5 | 6 | int main() { 7 | int ca = 1, a, b; 8 | char s[10]; 9 | while (scanf("%d%s%d", &a, s, &b) && s[0] != 'E') { 10 | printf("Case %d: ", ca++); 11 | if (strcmp(s, "==") == 0) { 12 | if (a == b) printf("true\n"); 13 | else printf("false\n"); 14 | } 15 | if (strcmp(s, "<=") == 0) { 16 | if (a <= b) printf("true\n"); 17 | else printf("false\n"); 18 | } 19 | if (strcmp(s, ">=") == 0) { 20 | if (a >= b) printf("true\n"); 21 | else printf("false\n"); 22 | } 23 | if (strcmp(s, "<") == 0) { 24 | if (a < b) printf("true\n"); 25 | else printf("false\n"); 26 | } 27 | if (strcmp(s, ">") == 0) { 28 | if (a > b) printf("true\n"); 29 | else printf("false\n"); 30 | } 31 | if (strcmp(s, "!=") == 0) { 32 | if (a != b) printf("true\n"); 33 | else printf("false\n"); 34 | } 35 | 36 | } 37 | return 0; 38 | } -------------------------------------------------------------------------------- /ICPC.Regional/2009.Phuket/la4721.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Phuket: Nowhere Money 2 | // ACM-ICPC Live Archive 4721 3 | #include 4 | #include 5 | #include 6 | typedef long long ll; 7 | #define N 100 8 | ll dp[N], ans[N]; 9 | int main() { 10 | //freopen("in.txt", "r", stdin); 11 | int i, sz; 12 | ll x; 13 | dp[1] = 1, dp[2] = 2; 14 | for (i = 3; i <= 90; i++) 15 | dp[i] = dp[i - 2] + dp[i - 1]; 16 | while (scanf("%lld", &x) != EOF) { 17 | printf("%lld\n", x); 18 | sz = 0; 19 | for (i = 90; x;) { 20 | if (x >= dp[i]) ans[sz++] = i, x -= dp[i]; 21 | i--; 22 | } 23 | for (i = 0; i < sz; i++) 24 | printf("%lld ", ans[i]); 25 | printf("\n"); 26 | for (i = 0; i < sz; i++) 27 | printf("%lld ", dp[ans[i]]); 28 | printf("\n\n"); 29 | } 30 | return 0; 31 | } -------------------------------------------------------------------------------- /ICPC.Regional/2009.Shanghai/img/la4750_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/ICPC.Regional/2009.Shanghai/img/la4750_img1.jpg -------------------------------------------------------------------------------- /ICPC.Regional/2009.Southwestern_Europe/la4504.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Southwestern Europe: Trick or Treat 2 | // ACM-ICPC Live Archive 4504 3 | // POJ 3873 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | const int N = 50005; 9 | const double INF = 1e30; 10 | 11 | int n; 12 | double x[N], y[N]; 13 | 14 | double check(double xm, double &low, double &high){ 15 | double farDis = -1, farX; 16 | for (int i = 0; i < n; i++){ 17 | double d = (x[i] - xm) * (x[i] - xm) + y[i] * y[i]; 18 | if (d > farDis) 19 | farDis = d, farX = x[i]; 20 | } 21 | xm < farX ? low = xm : high = xm; 22 | return farDis; 23 | } 24 | 25 | int main(){ 26 | while (scanf("%d", &n) && n){ 27 | double d, low, high; 28 | low = INF; high = -INF; 29 | for (int i = 0; i < n; i++){ 30 | scanf("%lf%lf", &x[i], &y[i]); 31 | low = x[i] < low ? x[i] : low; 32 | high = x[i] > high ? x[i] : high; 33 | } 34 | do{ 35 | d = check((high + low) / 2.0, low, high); 36 | } while (high - low > 1e-6); 37 | printf("%.6lf %.6lf\n", high, sqrt(d)); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Southwestern_Europe/la4505.cpp: -------------------------------------------------------------------------------- 1 | // 2009 Southwestern Europe: Working at the Restaurant 2 | // ACM-ICPC Live Archive 4505 3 | // POJ 3874 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int main() { 9 | int n, x, begin = true; 10 | char cmd[10]; 11 | 12 | while (scanf("%d", &n) && n) { 13 | int pile1 = 0, pile2 = 0; 14 | if (begin) 15 | begin = false; 16 | else 17 | printf("\n"); 18 | 19 | while (n--) { 20 | scanf("%s%d", cmd, &x); 21 | if (strcmp(cmd, "DROP") == 0) { 22 | printf("DROP 2 %d\n", x); 23 | pile2 += x; 24 | } else { 25 | if (pile1) { 26 | int take = min(x, pile1); 27 | printf("TAKE 1 %d\n", take); 28 | x -= take, pile1 -= take; 29 | } 30 | if (x) { 31 | printf("MOVE 2->1 %d\n", pile2); 32 | pile1 += pile2; 33 | pile2 = 0; 34 | x = min(pile1, x); 35 | printf("TAKE 1 %d\n", x); 36 | pile1 -= x; 37 | } 38 | } 39 | } 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Southwestern_Europe/la4512.cpp: -------------------------------------------------------------------------------- 1 | // CII 4512 2 | // 2009 Southwestern Europe: Happy Telephones 3 | #include 4 | #define N 10005 5 | struct RANGE { 6 | int b, e; 7 | void get() { 8 | scanf("%d%d", &b, &e); 9 | e = b + e; 10 | } 11 | }; 12 | RANGE rl[N]; 13 | int main() { 14 | int i, n, m, a, b; 15 | while (scanf("%d%d", &n, &m) && n) { 16 | for (i = 0; i < n; i++) { 17 | scanf("%d%d", &a, &b); 18 | rl[i].get(); 19 | } 20 | while (m--) { 21 | int ans = 0; 22 | RANGE r; 23 | r.get(); 24 | for (i = 0; i < n; i++) { 25 | if (r.e <= rl[i].b || r.b >= rl[i].e) continue; 26 | ans++; 27 | } 28 | printf("%d\n", ans); 29 | } 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Wuhan/la4485.cpp: -------------------------------------------------------------------------------- 1 | // CII 4485 2 | // 2009 Wuhan: Crossing Rivers 3 | #include 4 | 5 | int main() { 6 | double d, len, l, v, p, ans = 0; 7 | int n, i, ca = 1; 8 | while (scanf("%d%lf", &n, &d) && d) { 9 | ans = 0, len = d; 10 | for (i = 0; i < n; i++) { 11 | scanf("%lf%lf%lf", &p, &l, &v); 12 | ans += l * 2 / v; 13 | len -= l; 14 | } 15 | ans += len; 16 | printf("Case %d: %.3lf\n\n", ca++, ans); 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ICPC.Regional/2009.Wuhan/la4486.cpp: -------------------------------------------------------------------------------- 1 | // CII 4486 2 | // 2009 Wuhan: Download Manager 3 | #include 4 | int main() { 5 | int n, T, ca = 1; 6 | double B, sum; 7 | while (scanf("%d%d%lf", &T, &n, &B) && T) { 8 | sum = 0; 9 | while (T--) { 10 | double a, p; 11 | scanf("%lf%lf", &a, &p); 12 | sum += a * (100 - p) / 100.0; 13 | } 14 | printf("Case %d: %.2lf\n\n", ca++, sum / B); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.East_Central_NA/la4905.cpp: -------------------------------------------------------------------------------- 1 | // CII 4905 2 | // 2010 East Central NA: Pro-Test Voting 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 105 8 | int money, n; 9 | int pop[N], Ip[N], delta[N]; 10 | int dp[N][N], from[N][N]; 11 | int get(int idx, int mon) { 12 | double ans = pop[idx] * (Ip[idx] + mon / (mon + 10.1) * delta[idx]) / 100; 13 | return int(ans + 0.5); 14 | } 15 | void solve() { 16 | int i, j, k; 17 | for (i = n - 1; i >= 0; i--) 18 | scanf("%d%d%d", &pop[i], &Ip[i], &delta[i]); 19 | for (i = 0; i <= money; i++) { 20 | dp[0][i] = get(0, i); 21 | from[0][i] = i; 22 | } 23 | for (i = 1; i < n; i++) 24 | for (j = 0; j <= money; j++) { 25 | dp[i][j] = 0; 26 | for (k = 0; k <= j; k++) { 27 | int nans = dp[i - 1][j - k] + get(i, k); // make j-k as small as possible 28 | if (nans >= dp[i][j]) { 29 | dp[i][j] = nans; 30 | from[i][j] = k; 31 | } 32 | } 33 | } 34 | 35 | printf("%d\n", dp[n - 1][money]); 36 | for (i = n - 1; i >= 0; i--) { 37 | if (i != n - 1) printf(" "); 38 | printf("%d:%d", n - 1 - i, from[i][money]); 39 | money -= from[i][money]; 40 | } 41 | 42 | } 43 | int main() { 44 | int T = 0; 45 | while (scanf("%d%d", &money, &n) && money) { 46 | printf("Case %d: ", ++T); 47 | solve(); 48 | printf("\n"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Hangzhou/la4840.cpp: -------------------------------------------------------------------------------- 1 | // CII 4840 2 | // 2010 Hangzhou: National Day Parade 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 60 9 | vector pos[N]; 10 | int iabs(int x) { 11 | return x < 0 ? -x : x; 12 | } 13 | int main() { 14 | int n, m; 15 | while (scanf("%d%d", &n, &m) && n) { 16 | int i, j, k, x, y, ans = 1 << 30, tans; 17 | for (i = 0; i < n; i++) 18 | pos[i].clear(); 19 | for (i = 0; i < n * n; i++) { 20 | scanf("%d%d", &x, &y); 21 | pos[x - 1].push_back(y); 22 | } 23 | 24 | for (i = 0; i < n; i++) 25 | sort(pos[i].begin(), pos[i].end()); 26 | for (i = 1; i <= m - n; i++) { 27 | tans = 0; 28 | for (j = 0; j < n; j++) 29 | for (k = 0; k < n; k++) 30 | tans += iabs(pos[j][k] - (i + k)); 31 | ans = min(tans, ans); 32 | } 33 | printf("%d\n", ans); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5067.cpp: -------------------------------------------------------------------------------- 1 | // CII 5067 2 | // 2010 Tokyo: Membership Management 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define N 2000 10 | char s[2000]; 11 | int deg[2000], vis[2000], ans; 12 | vector sub[1000]; 13 | void dfs(int x) { 14 | vis[x] = 1; 15 | if (sub[x].size() == 0) ans++; 16 | else { 17 | for (int i = 0; i < (int)sub[x].size(); i++) 18 | if(!vis[sub[x][i]])dfs(sub[x][i]); 19 | } 20 | } 21 | int main() { 22 | int i, j, n; 23 | while (scanf("%d", &n) && n) { 24 | int idx = 1; 25 | ans = 0; 26 | map m; 27 | 28 | memset(vis, 0, sizeof(vis)); 29 | memset(deg, 0, sizeof(deg)); 30 | gets(s); 31 | for (i = 0; i < n; i++) { 32 | string t; 33 | int gid; 34 | gets(s); 35 | for (j = 0; s[j] != ':'; j++) 36 | t += s[j]; 37 | if (m.find(t) == m.end()) m[t] = idx++; 38 | gid = m[t]; 39 | j++; 40 | t = ""; 41 | for (; s[j] != '.'; j++) { 42 | if (s[j] == ',') { 43 | if (m.find(t) == m.end()) m[t] = idx++; 44 | sub[gid].push_back(m[t]); 45 | t = ""; 46 | } else t += s[j]; 47 | } 48 | if (m.find(t) == m.end()) m[t] = idx++; 49 | sub[gid].push_back(m[t]); 50 | } 51 | dfs(1); 52 | printf("%d\n", ans); 53 | for (i = 1; i < idx; i++) 54 | sub[i].clear(); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5067_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Membership Management 2 | 3 | ## Solution 4 | 模拟题。使用map对字符串进行存储,建立树,DFS统计即可。 5 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5068_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Balloon Collecting 2 | 3 | ## Solution 4 | 基本解法为动态规划。设dp[i][ball]表示处理了第i个球,当前车上载有的气球数目为ball个的时候,所行走的最短距离。在每次dp前先 判断时间是否允许,如果无论怎样都解决不了就抛出NG。否则进行dp。dp[i][0]在计算完dp[i][1]、dp[i][2]、dp[i][3]之 后处理。在可以接到下一个球的情况下,易得载有越多的球回到原点越好,答案越优。 5 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5069_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Towns along a Highway 2 | 3 | ## Solution 4 | 5 | Solution 6 | 7 | 假设读入的数据按题目给出的顺序存储在数组d之中,可以知道d[0]必定是dist[1,n],而d[1]只有两种可能:dist[1,n-1]或 dist[2,n]。我们有更加强的结论:假设[1,l]以及[r,n]这两个区间的内城市的坐标已经知道,并且在d数组删去所有已经知道的距离 dist[i,j](i,j都在[1,l]或[r,n]区间内,且i≠j)。此时[l+1,r-1]区间内的城市坐标并不知道,可以认定,此时d数组中最 大的数字d[k],只有两种可能:d[k]=dist[1,r-1]或者d[k]=dist[l+1,n]。因为这时剩下的未知距离,要么全部小于等于 dist[1,r-1],要么全部小于等于dist[l+1,n]。 8 | 9 | 因此,可以按照以下策略进行搜索:搜索函数为dfs(l,r),表示[l+1,r-1]区间内的城市坐标未知。寻找d数组最大的数字 d[k],分别尝试把d[k]作为dist[1,r-1]或者dist[l+1,n],然后求出所有已知距离,从d数组中删去。如果无法删去(找不到), 那么说明这种尝试不合法。如果合法,那么就继续搜索下去。若d[k]作为dist[1,r-1],那么下一步进行的就是dfs(l,r-1)。若d[k] 作为dist[l+1,n],那么下一步进行的就是dfs(l+1,r)。 10 | 11 | 以上搜索方法复杂度为O(n2n)。 12 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5070_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Awkward Lights 2 | 3 | ## Solution 4 | 把每个位置的开关的状态都看成一个变量xi,xi=1或xi=0分别表示触动之或不触动,那么可以把问题抽象成一个方程组。设第k个灯,其当前状态为st,st=1表示灯亮,st=0表示灯灭,此灯受到开关xk1,xk2,...,xkn的影响,那么有方程: 5 | 6 | (xk1+xk2+...+xkn) mod 2 = st 7 | 8 | 各个等式联立后,得到一个对2的同余方程组,可以使用高斯消元的方法解决。消元过程中的不少运算可以使用位运算代替。 9 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5071_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: The Two Men of the Japanese Alps 2 | ## Solution 3 | 4 | 题目可以抽象成一个最短路的模型。由于两个人必须处在所处相同的高度,用状态dis[x][y][h]来表示左边的人在第x条线段,右边的人在第y条线段,两人处于h高度时,所需走的最短路程,状态数目为100的三次方。在(x,y,h)的状态下,两人的运动可能会有如下情况:(-> <-)(<- ->)(-> ->)(<- <-)(S <-)(S ->)(<- 5 | S)(-> S)。其中,S表示某个人静止不动。如果某个运动合理(扩展后高度仍相等),那么求最短路的时候就可以扩展。 6 | 7 | 把山峰之间的关系(点与点之间的距离等等)预处理出来之后,使用dijkstra算法求最短路即可。 8 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5072.cpp: -------------------------------------------------------------------------------- 1 | // CII 5072 2 | // 2010 Tokyo: Find the Multiples 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // Hash table 8 | struct HASHNODE { 9 | int st, next, v; 10 | }; 11 | #define MOD 1000003 12 | HASHNODE HE[MOD]; 13 | int HG[MOD], htot; 14 | void hinit() { 15 | htot = 0; 16 | memset(HG, -1, sizeof(HG)); 17 | } 18 | int insert(int x) { 19 | int i, p = x % MOD; 20 | for (i = HG[p]; ~i; i = HE[i].next) 21 | if (HE[i].st == x) return i; 22 | HASHNODE e = { x, HG[p], 0 }; 23 | HG[p] = htot; 24 | HE[htot++] = e; 25 | return htot - 1; 26 | } 27 | 28 | // End of Hash table 29 | #define N 100005 30 | int a[N]; 31 | int main() { 32 | int n, s, w, q; 33 | while (scanf("%d%d%d%d", &n, &s, &w, &q) && n) { 34 | int g = s, i; 35 | // Generate the sequence 36 | for (i = 0; i < n; i++) { 37 | a[i] = (g / 7) % 10; 38 | if (g % 2 == 0) { 39 | g = (g / 2); 40 | } else { 41 | g = (g / 2) ^ w; 42 | } 43 | } 44 | hinit(); 45 | int re = 0, mul = 1, ans = 0, cnt = 0; 46 | for (i = n - 1; i >= 0; i--) { 47 | if (q == 2 || q == 5) { 48 | if (a[i] % q == 0) cnt++; 49 | if (a[i]) ans += cnt; 50 | } else { 51 | re = (re + mul * a[i]) % q; 52 | mul = mul * 10 % q; 53 | cnt = ++HE[insert(re)].v; 54 | if (a[i]) { 55 | ans += cnt; 56 | if (re) ans--; 57 | } 58 | } 59 | 60 | } 61 | printf("%d\n", ans); 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5072_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Find the Multiples 2 | 3 | ## Solution 4 | 5 | 先求出序列A。设A的组成为a1a2a3...an,由akak+1...an组成的数字为Sk。如果Sa mod Q = Sb mod Q,且a<b,那么有(Sa-Sb) mod Q=0,而Sa-Sb也就是A序列中第a位与第b位数字之间组成的数,也就是题目要统计的对象。 6 | 7 | Sk可以边乘十,边累加、边求余进行计算,每次都检查Sk mod Q,看看前面该余数在前面出现了多少次。如果Sk mod Q=0,那么答案就加上该余数在前面出现的次数;如果Sk mod Q≠0,那么答案就加上该余数在前面出现的次数减一。注意,如果ak为0,就不需要累加,因为题目不需要统计以0开头的数字。这个统计过程可以使用一个类似map的结构辅助。 8 | 9 | 对于Q为2或5需要特判。因为这两个素数比较特殊。如2,一旦当前数位上出现2的倍数,那么不管a的前面是什么数字,都可与该数位构成2的倍数。5也是如此。因此这两个数字需要特殊处理。 10 | 11 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5074_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Where's Wally 2 | 3 | ## Summary 4 | 5 | 给出两个二维01阵:image与pattern,要求找出pattern在image之中出现了多少次。pattern可以作九十度旋转,也可以镜像倒转。 6 | ## Solution 7 | 8 | image的大小为h × w,而pattern的大小为p × p,可以考虑先进行Rabin Karp Hash,然后再进行KMP匹配的方法。具体实现是: 9 | 10 | 先把image的每一行看成一个字符串,把该字符串每p个位Hash成一个数字。也就是1到p位hash成一个数字,2到p+1位hash 成一个数字…………使用RK Hash对每一行进行操作,可以使复杂度为O(w)。对image每一行都这样处理后,我们得到一个h行,w-p+1列的二维数组,其中每个元素都是一个 数字。设该二维数组为h1[h][w-p+1]。 11 | 12 | 然后把pattern也这样进行Hash。那么得到一个“列向量”:pattern每一行都被Hash成一个数字,一共有p行。设该一维数 组为h2[p]。此时,如果h2[i] == h1[a][b],就说明image之中第a行从第b个字符开始,与pattern的第i行完全匹配。因为h1[a][b]是由h1第a行的第b个字符到 第b+p-1个字符Hash而成的,代表了这些字符的信息。 13 | 14 | 然后就进入了最后一步,枚举h1的每一个列,抽出来,与h2进行KMP匹配。题目规定每个地方只能计算一次,因此如果发现匹配,那么必须记录下来哪个地方匹配了。累加匹配次数即可得到答案。 15 | 16 | 题目说pattern可以进行旋转、镜像等操作,可以把pattern进行旋转、镜像,然后再重复上述的部分步骤。 17 | 18 | 由于RK Hash是一个不确定的算法,存在一定的错误概率,可以通过二次HASH提高正确率。但由于以下代码使用一次Hash即AC了,因此没有采用更为保险的二次Hash方法。 19 | 20 | 该算法总复杂度为O(w*h)。 21 | -------------------------------------------------------------------------------- /ICPC.Regional/2010.Tokyo/5075_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 Tokyo: Intersection of Two Prisms 2 | 3 | ## Summary 4 | 5 | 有两个高度无限的直棱柱,一个垂直于xOy平面,给出其在xOy横截面上的坐标;一个垂直于xOz平面,给出其在xOz横截面上的坐标。两个直棱柱的横截面都是凸多边形,求这两个直棱柱相交部分的面积。 6 | 7 | ## Solution 8 | 9 | 两个直棱柱的横截面多边形都有x轴的坐标,而且坐标都是整数,因此可以沿X方向,利用定积分的思想,按照△X=1的步长来进行积分,累计体积分量,汇总后即可得总体积。此时,通过画图可知道,每个积分单位上面的三维图形都是一个拟棱柱。(拟棱柱:上底与下底平行,侧面都是梯形或者三角形)拟棱柱有体积公式:V=(S+4×S+S)/6。而且这个拟棱柱比较特殊,上底和下底都是矩形,面积容易求得。因此,我们只需要求出:位于xOy面上的多边形在Y轴方向由X=i或X=i+△X截得的长度py和cy,以及位于xOz面上的多边形在Z轴方向由X=i或X=i+△X截得的长度pz和cz。这两个长度相乘,py×pz和cy×cz就是X=i或X=i+△X时对应的两个底面积,也就对应上面体积公式的S和S。而4×S则等于(py+cy)×(pz+cz)。代入体积公式,可以求得单个拟棱柱的体积。累加这些分量的体积,结果就是总体积的精确值。 10 | 11 | 因此,X=i时在Y或Z轴对应的长度比较容易找。直接枚举X=i经过横截面的哪些边即可。由于两个棱柱的截面都是凸多边形,X=i只会进多边形一次,出多边形一次,中间不会形成“空洞”。 12 | 13 | 下面有两个代码。代码1是在求X=i时,遍历另一个横截面多边形数组,找出X在这个多边形中截得的长度。代码2是预先把X=i时,把在两个多边形截得的长度预处理出来,计算面积时直接使用。 14 | 15 | 可以看出,如果把S、S与S分别改写成f(x),f(x+△X/2)与f(x+△X),f(x)代表某个横截矩形的面积,那么该公式与辛普森积分公式形式上一致。这是一种巧合么? 16 | 17 | -------------------------------------------------------------------------------- /POJ/img/poj3558.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/POJ/img/poj3558.jpg -------------------------------------------------------------------------------- /POJ/img/poj3675_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/POJ/img/poj3675_1.jpg -------------------------------------------------------------------------------- /POJ/img/poj3675_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/POJ/img/poj3675_2.jpg -------------------------------------------------------------------------------- /POJ/img/poj3675_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/POJ/img/poj3675_3.jpg -------------------------------------------------------------------------------- /POJ/img/poj3675_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/POJ/img/poj3675_4.jpg -------------------------------------------------------------------------------- /POJ/poj1662.pas: -------------------------------------------------------------------------------- 1 | { 2 | POJ 1662 3 | POJ Monthly--2004.05.15: Coins 4 | } 5 | program pku1662; 6 | {$APPTYPE CONSOLE} 7 | 8 | var 9 | m,t:Int64; 10 | i:longint; 11 | function so1ve(m:Int64):Int64; 12 | var i,t,d:Int64; 13 | flag:boolean; 14 | begin 15 | if (m=1)then 16 | so1ve:= 2 17 | else 18 | begin 19 | d:=2*m+1; 20 | t:= 2; 21 | i:= 1; 22 | flag:=False; 23 | repeat 24 | if (t=1)then 25 | begin 26 | so1ve:= i*m; 27 | flag:=True; 28 | end 29 | else if (t=2*m)then 30 | begin 31 | so1ve:=i*m-1; 32 | flag:=True; 33 | end 34 | else 35 | t:= (t*2)mod d ; 36 | i:=i+1; 37 | until flag; 38 | end 39 | end; 40 | begin 41 | read(t); 42 | for i:= 1 to t do 43 | begin 44 | read (m); 45 | writeln ( so1ve(m) ); 46 | end; 47 | end. 48 | -------------------------------------------------------------------------------- /POJ/poj1830.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ 1830 开关问题 2 | 3 | ## Summary 4 | 5 | 有n个开关,每当触动一个开关,有可能会影响其他开关的状态。现在给出开关影响的状态列表,问,所有的开关,能否从一个初始状态,通过一系列变换切 换到另一个状态。若能,给出方案数。 6 | 7 | ## Solution 8 | 9 | 这个问题可以转化成一个整数方程组,可以使用高斯消元来解决之。 10 | 11 | 方程组的系数矩阵是一个方阵。每一个未知数代表该开关是否需要按下,若需要,x=1,若不需要,x=0。一条式子就表示一个开关最终的状 态。例如,对于一个开关: 12 | 13 | A1x1+A2x2+...ANxn = S 14 | 15 | 如果第i个开关的按下会对这个开关影响,那么Ai=1,否则Ai=0。当然,自己按下,也会对自己影响。如果开关的状态和原先一样,那么 S=0,如果不一样则S=1。因为明显,一个开关被影响偶数次,状态不变,影响奇数次,状态改变。 16 | 17 | 列好方程组后,只需要将其化成三角矩阵,就可以知道这个方程有解还是没解。若方程的自由变元数为M个,那么答案就是2M。。 意思是这些自由的开关的状态是可以任意组合的。 18 | -------------------------------------------------------------------------------- /POJ/poj1830.cpp: -------------------------------------------------------------------------------- 1 | // POJ 1830 开关问题 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | #define N 33 7 | int mm[N][N]; 8 | 9 | int gauss(int n) { 10 | int i, j, k, row, col; 11 | for (k = col = 0; k < n && col < n; k++, col++) { 12 | row = k; 13 | for (i = k + 1; i < n; i++) 14 | if (mm[i][col]) { 15 | row = i; 16 | break; 17 | } 18 | if (k != row) for (i = k; i <= n; i++) 19 | swap(mm[k][i], mm[row][i]); 20 | if (mm[k][col] == 0) { 21 | k--; 22 | continue; 23 | } 24 | for (i = k + 1; i < n; i++) 25 | if (mm[i][col]) for (j = col; j <= n; j++) 26 | mm[i][j] ^= mm[k][j]; 27 | } 28 | for (i = k; i < n; i++) 29 | if (mm[i][n]) return -1; 30 | return n - k; 31 | } 32 | void solve() { 33 | int beg[N], end[N], i, a, b, n; 34 | memset(mm, 0, sizeof(mm)); 35 | scanf("%d", &n); 36 | for (i = 0; i < n; i++) 37 | scanf("%d", beg + i); 38 | for (i = 0; i < n; i++) 39 | scanf("%d", end + i); 40 | for (i = 0; i < n; i++) 41 | mm[i][n] = beg[i] ^ end[i], mm[i][i] = 1; 42 | while (scanf("%d%d", &a, &b) && (a + b)) 43 | mm[b - 1][a - 1] = 1; 44 | int ans = gauss(n); 45 | if (ans == -1) printf("Oh,it's impossible~!!\n"); 46 | else printf("%d\n", 1 << ans); 47 | } 48 | int main() { 49 | //freopen("in.txt", "r", stdin); 50 | int T; 51 | scanf("%d", &T); 52 | while (T--) 53 | solve(); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /POJ/poj2096.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2004 Northeastern Europe, Northern Subregion: Collecting Bugs 2 | ## Summary 3 | 4 | 有一个人收集软件的bug. 他将bug分成n个种类, 而一个软件有s个子系统. 问: 在他每天收集一个bug的情况下, 他要收集bug中, 来自每个种类的bug都有, 来自每个子系统bug都有, 数学期望需要多少天? 5 | ## Solution 6 | 7 | 这是概率论里面的Markov过程的模型. 8 | 9 | 按照期望的定义, 我们很难通过迭代算出这么大的答案. 我们要换另外一种方法来计算. 设E[i,j]为发现了i个种类, 来自j个软件子系统的bug的前提下, 到达终点(也就是发现来自所有种类, 所有系统的bug)的提案天数的数学期望. 10 | 11 | 明显, E[n,s]是0, E[0,0]就是我们所要求的. 12 | 13 | 我们有如下递推式子: 14 |
15 | E[i,j] =
16 | 1
17 | + E[i+1,j+1] * (n - i)(s - j) / ns
18 | + E[i,j+1] * i * (s - j) / ns
19 | + E[i+1,j] * (n - i) * j / ns
20 | + E[i,j] * ij/ns
21 | 
22 | 23 | 也就是说, 当前状态的数学期望, 能够表示为其他数学期望乘以其发生概率再加上当前转移的消耗(在这个题目中就是1天)得到. 稍作移项, 我们就可以得到右边不含E[i,j]的式子. 我们注意到, E[i,j]仅仅和E[i+1,j], E[i,j+1], E[i+1,j+1]有关系, 这意味着我们可以使用递推的方法, 从E[n,s]开始推, 解决这个问题. 24 | 25 | 注意, 要对式子进行适当的化简, 否则有可能会影响运算的精度. 26 | -------------------------------------------------------------------------------- /POJ/poj2096.cpp: -------------------------------------------------------------------------------- 1 | // POJ 2096 2 | // 2004 Northeastern Europe, Northern Subregion: Collecting Bugs 3 | #include 4 | #include 5 | #define N 1005 6 | double f[N][N]; 7 | int main() { 8 | int n, s, i, j; 9 | double ns; 10 | scanf("%d%d", &n, &s); 11 | memset(f, 0, sizeof(f)); 12 | ns = n * s; 13 | for (i = n; i >= 0; i--) 14 | for (j = s; j >= 0; j--) 15 | if (i != n || j != s){ 16 | f[i][j] = 17 | ( 18 | ns 19 | + f[i + 1][j + 1] * (n - i)*(s - j) 20 | + f[i][j + 1] * i * (s - j) 21 | + f[i + 1][j] * (n - i) * j 22 | ) / (ns - i * j ); 23 | } 24 | printf("%lf\n", f[0][0]); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /POJ/poj2928.Solution_CN.md: -------------------------------------------------------------------------------- 1 | ## 2005 MIT Programming Contest: A City of Skyscrapers 2 | ##### Summary 3 | 4 | 给出一个N*M的矩阵 (1 ≤ M ≤ 100 000), N (1 ≤ N ≤ 100 000)和c,C两个数字,现知道每一行和每一列的最大值,问这个矩阵所有元素的和可能的最小值和最大值。输出时最小值乘以c,最大值乘以C。 5 | ##### Solution 6 | 7 | 先把两个数组从小到大进行排序,最小值的做法和最大值的做法有所不同,下面分别说说: 8 | 9 | * 最小值: 10 | 11 | 尽量使ai=bj,这样能够尽量多”耗“题目给出的限制条件,若不能,则随便放置,除此之外,所有元素均为0。 12 | 13 | * 最大值 14 | 15 | 易得M[i][j] = M( A[i],B[j] ),但是不可能枚举每个点对,因此必须找到简便的方法统计。统计方法见代码。 16 | -------------------------------------------------------------------------------- /POJ/poj2932.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2005 MIT Programming Contest: Coneology 2 | ## Summary 3 | 给出n(n<=40000)个圆,且任意两个圆都不会相交,要求找出所有没有被包含的圆。 4 | ## Solution 5 | 6 | 可以使用扫描线+平衡树统计的方法解决. 7 | 8 | 圆A包含圆B,必定满足以下条件: 9 | 10 | 1. 在X轴上.圆A的区间为[x1,x2],圆B的区间为[x3,x4],那么必有[x1,x2]包含[x3,x4] 11 | 2. 在Y轴上.将区间重合的圆按照Y坐标的大小从小到大排序,那么包含事件必定发生在两个相邻的圆上. 12 | 13 | 在X轴上,可以使用排序+扫描线的方法处理.将每个圆拆成两部分,最左和最右,按照坐标排序. 14 | 15 | 在Y轴上,可以使用平衡树统计.每次向平衡树中插入或删除圆.在插入之前,检测当前圆是否已经被平衡树中的某些圆包含.如果包含了,则不需 要插入了.否则则添加到答案数组中. 16 | 17 | 下面的代码将Y方向也进行离散化了.这样保存进set里面就不需要另外写比较函数. 18 | -------------------------------------------------------------------------------- /POJ/poj3029.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Nordic 2006: Tour Guide 2 | ## Solution 3 | 由于题目的规模不大,因此可以枚举寻找顺序的全排列,找出最优的寻找顺序。 4 | 5 | 假设当前人在p1,速度为v,他要找到起始位置为p0,速度向量为v0的人,那么可以得到如下方程: 6 | 7 | dist((p0+v0t),p1)=vt,化成等式得: (p0.x+v0.x*t-p1.x)2+(p0.y+v0.y*t-p1.y)2=(vt)2 8 | 9 | 由于Guide的速度大于所有游客的速度,所以以上方程必定有正数解,解出t,就是Guide从当前位置出发,寻找位置为p0,速度为v0的游客的时间。 10 | 11 | 最后注意,由于每个人都是移动的,因此要更新每个游客的坐标位置。 12 | -------------------------------------------------------------------------------- /POJ/poj3033.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Nordic 2006: Traveling Salesman 2 | ## Solution 3 | 4 | 对于每个询问可以使用BFS找出最短路。题目的麻烦之处在于预处理。由于规模比较大,不恰当的预处理可能导致超时。 5 | 6 | 预处理时,可以使用Hash表保存边。Hash表的节点保存每条边的信息以及这条边有哪些多边形(使用vector记录)。每次扫描一个多 边形,依次扫描其中的边,如果在Hash表中找到,那么就可以找出这个多边形通过这条边能够与哪些多边形相连。若找不到,则新开一个节点。 7 | -------------------------------------------------------------------------------- /POJ/poj3034.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Nordic 2006: Whac-a-Mole 2 | ## Solution 3 | 4 | 使用动态规划解决这个问题。设DP[time][x][y]为在时间time结束后,在x,y位置能够获得的最高得分。 5 | 6 | 明显,DP[t][x][y] = max(DP[t-1][x2][y2] + hitmole((x2,y2)-(x,y)) in time t)。且dist((x2,y2),(x,y))<=d 7 | 8 | hitmole((x2,y2)-(x,y)) in time t,就是在时间t内,线段(x2,y2)-(x,y)经过的有Mole的整点。 9 | 10 | 整点可以通过枚举计算。枚举的方法是:设dx=|x-x2|,dy=|y-y2|,如果dx,dy均不为0,则线段(x2,y2)-(x,y)必定经过gcd(dx,dy)+1个整点,否则经过max(dx,dy)+1个整点,而且整点之间的距离是一样的。求出x的步长(dx/gcd(dx,dy)),y的步长(dy/gcd(dx,dy))后即可枚举整点了。注意dx,dy为0的情况的特殊处理。 11 | -------------------------------------------------------------------------------- /POJ/poj3035.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Nordic 2006: Random Walk 2 | ## Solution 3 | 4 | 可以使用DP解决这个问题。状态方程DP\[k\][x]表示在第k步产生数字x的概率。由于第一步的生成是等概率的,因此dp[0][x]=1/total。(total为总节点数,即1\<\ 4 | #include 5 | #define N 1<<11 6 | 7 | struct EDGE { 8 | int b, next; 9 | }; 10 | EDGE E[5000]; 11 | double dp[105][N]; 12 | int G[N], tot, deg[N]; 13 | void addedge(int a, int b) { 14 | EDGE e = { b, G[a] }; 15 | E[tot] = e; 16 | G[a] = tot++; 17 | } 18 | int main() { 19 | int K, n, m; 20 | while (scanf("%d%d%d", &K, &n, &m) && K) { 21 | int i, j, k, cnt; 22 | bool ok = 1; 23 | cnt = (1 << n); 24 | memset(deg, 0, sizeof(deg)); 25 | memset(G, -1, sizeof(G)); 26 | tot = 0; 27 | while (m--) { 28 | int a, b; 29 | scanf("%d%d", &a, &b); 30 | addedge(a, b); 31 | addedge(b, a); 32 | deg[a]++, deg[b]++; 33 | } 34 | memset(dp, 0, sizeof(dp)); 35 | for (i = 0; i < cnt; i++) { 36 | dp[0][i] = 100.0 / cnt; 37 | } 38 | for (k = 1; k < K && ok; k++) { 39 | for (i = 0; i < cnt; i++) { 40 | dp[k][i] = 0; 41 | for (j = G[i]; ~j; j = E[j].next) { 42 | dp[k][i] += dp[k - 1][E[j].b] / deg[E[j].b]; 43 | } 44 | } 45 | for (i = 0; i < n; i++) { 46 | double p = 0; 47 | for (j = 0; j < cnt; j++) 48 | if ((1 << i) & j) p += dp[k][j]; 49 | if (p <= 25 || p >= 75) ok = 0; 50 | } 51 | } 52 | puts(ok ? "Yes" : "No"); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /POJ/poj3036.cpp: -------------------------------------------------------------------------------- 1 | // POJ 3036 2 | // Nordic 2006: Honeycomb Walk 3 | #include 4 | int main() { 5 | int ans[] = { 0, 0, 6, 12, 90, 360, 2040, 10080, 54810, 290640, 1588356, 6 | 8676360, 47977776, 266378112, 1488801600 }; 7 | int T, i; 8 | scanf("%d", &T); 9 | while (T--) { 10 | scanf("%d", &i); 11 | printf("%d\n", ans[i]); 12 | } 13 | return 0; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /POJ/poj3225.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # PKU Local 2007 (POJ Monthly--2007.04.28): Help with Intervals 2 | 3 | ## Solution 4 | 5 | 此题可以用线段树解决.线段树c表示状态. 6 | 7 | * c==1,表示该区间取反. 8 | * c==2,表示该区间被设为0 9 | * c==3,表示该区间被设为1 10 | 11 | 数组a用于保存最终结果.要解决开闭区间的问题,可以将区间的左端和右端都乘以2.这样就不用考虑区间开与闭.此时,线段树建为点数,例如: 12 | 0:端点0 13 | 1:区间0-1 14 | 2:端点1 15 | 3:区间1-2 16 | 4:端点2 17 | 5:区间2-3 18 | ...... 19 | 20 | 通过取反,设0,设1三个操作组合,能够轻易地完成题目要求的运算. 各个操作的设置方法如下: 21 | 22 | U T:将(L,R)设置为1即可. 23 | I T:将(0,L-1)和(R+1,max)设为0即可 24 | D T:将(L,R)设置为0即可. 25 | C T:将(0,max)取反,然后再将(0,L-1)和(R+1,max)设为0即可 26 | S T:将(L,R)取反即可 27 | -------------------------------------------------------------------------------- /POJ/poj3301.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Waterloo Local Contest, 2007.7.14: Texas Trip 2 | 3 | ## Summary 4 | 给出平面上有N个点,要求一个面积最小的正方形覆盖所有的点. 5 | ## Solution 6 | 7 | 假设正方形的边是轴对齐的,将所有的点旋转,求出最上下左右的点的位置,那么就可以求出这个正方形的面积.因为解析几何的旋转变换是正交变换,不会改变各个点之间的距离.每次旋转一个很小的角度,求出最小面积.找出最优的角度,然后在最优的角度附近微分,旋转,重复直到10次以上,即可精确求出答案. 8 | 9 | 由于对称性,实际上第一次只需要旋转90度即可. 10 | -------------------------------------------------------------------------------- /POJ/poj3528.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Founder Monthly Contest – 2008.07.27: Ultimate Weapon 2 | ## Summary 3 | 4 | 给出空间中的N(N<=500)个点,求三维凸壳的表面积。数据保证没有四个点共面的情况。 5 | 6 | ## Solution 7 | 8 | 分类讨论: N=2,答案为0。 9 | 10 | N=3,没有凸壳,直接返回平面的表面积。 11 | 12 | N>=4,使用增量法求三维凸壳。 13 | 14 | 增量法的思路是: 15 | 16 | 首先初始化一个初始凸壳,加入前四个点即可(如果题目不保证任意四个点不共面,那么就必须先找出四个不共面的点)。 17 | 18 | 然后依次加入后面的点,然后枚举现有凸壳的面相对与新加的点是否可视。可视的解释是:凸壳上的每一个面都有一个法向量,法向量的方向朝外。如果该面上的一个点到新加点的向量与法向量反向,那么就说明相对与当前的新加点,凸壳的这个面是不可视的。否则就是可视的。每次新加入一个点,如果这个点不在当前凸壳的内部,那么就会形成一个新的隆起的锥状立方体。如果一个面是可视的,那么这个面必然要被删除,而隆起状的立方体上的面就是新加入的面。 19 | 20 | 如此反复,直到所有的点被处理,既可以得三维凸壳。 21 | 22 | 实现的一些细节问题: 23 | 24 | 1. 使用三角形的结构体代表凸壳上的面。 25 | 2. 在加入新的点P的时候,除了删除可视的面,还要加入新的面(这些面位于隆起的锥状立方体上)。方法是:如果凸壳上的边SEG,相邻的两个面都是可视的,那么这条边不会出现在新的凸壳中。如果这条边相邻的面一个可视,一个不可视,那么这一条边必定是新的隆起的锥状立方体的一个底边,这时可以为凸壳加入一个新的面(P,SEG.a,SEG.b)。 26 | 3. 判断一个面是否可视的方法:设center为初始化是的四面体的中点。对于面M,如果新加点P与center均位于M的同一侧,那么这个面不可视。判断是否位于同一侧可以使用空间中的定向体积判断。定向体积是a*b●c(也就是a,b,c三个向量的混合积)。如果定向体积相同,则表示位于面的同一侧。 27 | -------------------------------------------------------------------------------- /POJ/poj3532.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Founder Monthly Contest – 2008.03.16: Resistance 2 | ## Solution 3 | 根据基尔霍夫定律,列出电势的方程组,使用高斯消元解决即可. 4 | 5 | 注意处理电阻为0的情况. 6 | -------------------------------------------------------------------------------- /POJ/poj3558.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Northeastern Europe 2005, Western Subregion: Map Generator returns (MG-II) 2 | ## Summary 3 | 给出你n个点, (n <= 20), 对于每个点对, 其相连的概率为r, 问整个图所有顶点连通的概率是多少? 4 | 5 | ## Solution 6 | 7 | 设题目所求的概率为p(n), 对于每个n, 我们从不连通的概率p'(n)角度考虑. 那么p(n) = 1-p'(n). 8 | 9 | 考虑含结点1的连通块C, |C| = k. 由于不连通,有k < n成立. 则有C(n - 1, k – 1)种方法选择另k-1个结点与结点1组成C. 所以有C(n - 1, k – 1) * p(k)的概率能够组成C. 剩下的节点必定不与C连通, 因此连通块C中有k个点, 其余的有n-k个点, 一共有k*(n-k)条边, 那么这些边都不连通的概率就是(1-r)k*(n-k). 那些n-k个点的连通状况不用考虑, 因此最终答案就是: 10 | 11 | ![Alt text](https://github.com/pkkj/ACM-ICPC-OJ-Code/raw/master/POJ/img/poj3558.jpg "POJ 3558 Image 1") 12 | -------------------------------------------------------------------------------- /POJ/poj3558.cpp: -------------------------------------------------------------------------------- 1 | // POJ 3558 2 | // Northeastern Europe 2005, Western Subregion: Map Generator returns (MG-II) 3 | #include 4 | #include 5 | #define N 21 6 | double C[N][N], pow[110], f[N]; 7 | 8 | int main() { 9 | int i, j, n; 10 | double p; 11 | scanf("%d%lf", &n, &p); 12 | for (i = 0; i <= n; i++) { 13 | C[i][0] = C[i][i] = 1.0; 14 | for (j = 0; j < i; j++) 15 | C[i][j] = C[i - 1][j] + C[i - 1][j - 1]; 16 | } 17 | pow[1] = 1.0 - p; 18 | for (i = 2; i <=((n + 1) / 2) * ((n + 1) / 2); i++) 19 | pow[i] = pow[i - 1] * (1.0 - p); 20 | f[1] = 1, f[2] = p; 21 | for (i = 3; i <= n; i++) { 22 | f[i] = 1.0; 23 | for (j = 1; j < i; j++) 24 | f[i] -= C[i - 1][j - 1] * f[j] * pow[j * (i - j)]; 25 | } 26 | printf("%.15lf\n", f[n]); 27 | } 28 | -------------------------------------------------------------------------------- /POJ/poj3562.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # Northeastern Europe 2005, Western Subregion: “Roman” corridor 2 | ## Solution 3 | 4 | 这个题目可以看成是一个在Trie树上的匹配问题。首先,我们建立一棵Trie树,把1-4000的罗马数字都保存到这个Trie树里面,然后再在给出的字母矩阵中进行DFS,前提是按照Trie树的合法路径走。在Trie树上还有一个节点叫做min,用于保存在这个节点为根的子树上所能得到罗马数字的最小值,可以在DFS时利用这个信息进行有效剪枝。 5 | -------------------------------------------------------------------------------- /POJ/poj3675.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Founder Monthly Contest – 2008.07.27: Telescope 2 | 3 | ## Summary 4 | 给出一个圆,知道半径,圆心位于原点。再给出一个多边形,求多边形与圆交的面积。 5 | 6 | ## Solution 7 | 可以先把多边形剖分成若干个三角形,然后累加这些三角形与圆交的有向面积。三角剖分时可以选定一个点为原点,然后按一定顺序枚举多边形所有的边,构成三角形即可。那么这个问题就转化为计算圆与三角形的交。 8 | 9 | 由于圆心就是原点,那么这个三角形的其中一个点就是圆心,问题得到极大的简化。在这种情况下,如图,圆与三角形的交有四种情况: 10 | 11 | 1.整个三角形都在圆里面,只需要计算三角形的面积。 12 | 13 | ![Alt text](https://github.com/pkkj/ACM-ICPC-OJ-Code/raw/master/POJ/img/poj3675_1.jpg "POJ 3675 Image 1") 14 | 15 | 2.一个点在圆外,一个点在圆内,计算一个三角形和一个扇形的面积。 16 | ![Alt text](https://github.com/pkkj/ACM-ICPC-OJ-Code/raw/master/POJ/img/poj3675_2.jpg "POJ 3675 Image 2") 17 | 18 | 3.两个点在圆外,且该线段和圆相交,要计算一个三角形和左右两个个扇形的面积。 19 | ![Alt text](https://github.com/pkkj/ACM-ICPC-OJ-Code/raw/master/POJ/img/poj3675_3.jpg "POJ 3675 Image 3") 20 | 21 | 4.两个点在圆外,且该线段不和圆相交,计算一个扇形面积即可。 22 | ![Alt text](https://github.com/pkkj/ACM-ICPC-OJ-Code/raw/master/POJ/img/poj3675_4.jpg "POJ 3675 Image 4") 23 | 24 | 这样,问题就转化成求扇形和三角形的面积。在这个过程中,我们还要求出直线与圆的交点。比较好的方法是列直线的向量参数方程与圆的轨迹方程联立求解。直线向量参数方程:(x,y)=P+tv;其中P是直线的一点,v是方向向量。而圆的轨迹方程就是x2+y2=R2。联立解出t,即可得到交点。 25 | -------------------------------------------------------------------------------- /POJ/poj3713.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Monthly Contest - 2008.12.28: Transferring Sylla 2 | ## Summary 3 | 给出一个顶点数为N,边数为M的图,N<=500, M<=20000。问这个图是否所有点对都存在三条不重合的路径。不重合的意思是路径之间没有相同的顶点。 4 | ## Solution 5 | 如果是判断是否存在两条不重合的路径,那么只需要对图进行DFS,判断其有没有割点即可。而这次是判断三条不重合的路径,因此可以枚举图中的顶点,删去,这时再判断图中是否存在割点即可。如果删点后的图存在割点,则说明这个图不是三连通的。 6 | -------------------------------------------------------------------------------- /POJ/poj3715.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Monthly Contest - 2009.02.22: Blue and Red 2 | 3 | ## Summary 4 | 5 | 给出一个二分图,求出去掉最少的点数,使得整个图中不存在连接两个不在同一个集合的边。要求输出方案,使被删除的点的id的字典序最小。 6 | ## Solution 7 | 8 | 首先,题目是一个最小点权的匹配问题,可以使用匈牙利算法。但是如何做到输出方案的字典序最小: 9 | 10 | 按照题目给出的点的顺序枚举点,模拟删除之,并进行匹配。如果删除这个点后,最大匹配减少1,那么这个点就是关键点,必须要取到答案里面去的。那么我们就输出这个点,并从图中真正删除之,最大匹配数相应减少1。由于我们是按照字典序进行这项操作的,因此取出来的答案必定字典序最小。 11 | 12 | 由于题目的规模比较大,我们可以使用邻接表保存这个图。 13 | -------------------------------------------------------------------------------- /POJ/poj3723.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Monthly Contest – 2009.04.05: Conscription 2 | 3 | ## Solutioin 4 | 5 | 贪心思想,因为钱能节省的尽量节省,因此用类似求最小生成树Kruskal的思想去进行贪心。 6 | -------------------------------------------------------------------------------- /POJ/poj3723.cpp: -------------------------------------------------------------------------------- 1 | // POJ 3723 2 | // POJ Monthly Contest – 2009.04.05: Conscription 3 | #include 4 | #include 5 | using namespace std; 6 | #define N 100005 7 | struct ITEM { 8 | int a, b, w; 9 | bool operator <(const ITEM x) const { 10 | return w > x.w; 11 | } 12 | }; 13 | int fa[N]; 14 | void init_set(int n) { 15 | int i; 16 | for (i = 0; i <= n; i++) 17 | fa[i] = i; 18 | } 19 | int find_root(int p) { 20 | if (fa[p] != p) fa[p] = find_root(fa[p]); 21 | return fa[p]; 22 | } 23 | void union_set(int p, int q) { 24 | int a = find_root(p), b = find_root(q); 25 | fa[b] = a; 26 | } 27 | ITEM el[N]; 28 | void solve() { 29 | int n, m, q, i; 30 | scanf("%d%d%d", &n, &m, &q); 31 | for (i = 0; i < q; i++) 32 | scanf("%d%d%d", &el[i].a, &el[i].b, &el[i].w); 33 | sort(el, el + q); 34 | long long ans = 0; 35 | init_set(n + m + 1); 36 | for (i = 0; i < q; i++) 37 | if (find_root(el[i].a) != find_root(el[i].b + n)) { 38 | union_set(el[i].a, el[i].b + n); 39 | ans -= el[i].w; 40 | } 41 | printf("%lld\n", ans + (n + m) * 10000); 42 | } 43 | int main() { 44 | int T; 45 | scanf("%d", &T); 46 | while (T--) 47 | solve(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /POJ/poj3724.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Monthly Contest – 2009.04.05: Find the parameter 2 | 3 | ## Solution 4 | DFS搜索。 5 | -------------------------------------------------------------------------------- /POJ/poj3724.cpp: -------------------------------------------------------------------------------- 1 | // POJ 3724 2 | // POJ Monthly Contest – 2009.04.05: Find the parameter 3 | #include 4 | #include 5 | #define X 0 6 | #define Y 1 7 | #define M 10 8 | double pl[22][2], best; 9 | int n, ans[12], tmp[12]; 10 | 11 | double f(double x) { 12 | double ans = 0; 13 | for (int i = 0; i < M; i++) 14 | ans += exp(tmp[i] * x); 15 | return ans; 16 | 17 | } 18 | void dfs(int x) { 19 | int low, i; 20 | if (x == M) { 21 | double tr = 0; 22 | for (i = 0; i < n && tr < best; i+=10) 23 | tr += fabs(f(pl[i][X]) - pl[i][Y]); 24 | if (tr < best) { 25 | best = tr; 26 | for (i = 0; i < M; i++) 27 | ans[i] = tmp[i]; 28 | } 29 | return; 30 | } 31 | if (x == 0) low = 1; 32 | else low = tmp[x - 1]; 33 | for (i = low; i <= M; i++) { 34 | tmp[x] = i; 35 | dfs(x + 1); 36 | } 37 | 38 | } 39 | int main() { 40 | //freopen("in.txt", "r", stdin); 41 | scanf("%d", &n); 42 | for (int i = 0; i < n; i++) 43 | scanf("%lf%lf", &pl[i][X], &pl[i][Y]); 44 | best = 1000000000000.0; 45 | dfs(0); 46 | for (int i = 0; i < M; i++) 47 | printf("%d\n", ans[i]); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /POJ/poj3728.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Monthly Contest – 2009.04.05: The merchant 2 | 3 | ## Summary 4 | 5 | 给出一棵N个节点的树,每个节点有一个权值wi。需要回答Q个询问,每次询问给出两个节点A,B。要你从A到B的路径上(注意是单向的),找到两个点,使得后经过的那个点的权值与靠前那个点权值的差值最大,输出该最大差值(如果最大差值为负则输出0) 6 | 7 | 数据范围:1 ≤ N, wi, Q ≤ 50000。 8 | ## Solution 9 | 10 | 由于树的形态是不变的,因此可以使用离线算法。这个题目与LCA有点类似,对于询问x,y,我们可以知道,所求的最大值可以出现在x-LCA(x,y)这一段,也可能出现在LCA(x,y)-y一段,也有可能出现在横跨LCA(x,y),也就是x-y这一段。因此,我们每个节点x维护四个权值: 11 | 12 | * mi[x]:从x到LCA[x,U]中的最小权值。 13 | * ma[x]:从x到LCA[x,U]中的最大权值。 14 | * opt1[x],从x到LCA[x,U]中能够取到的最优值,注意方向,是向根的。 15 | * opt2[x],从LCA[x,U]到x中能够取到的最优值,注意方向,是背根的。 16 | 17 | U这个点是询问x,y中的最近公共祖先。我们只要利用类似Tarjan算法的做法,每次求出处理完一个子树后,就对Tarjan算法所维护的并查集进行路径压缩,同时维护mi,ma,opt1,opt2四个值进行维护。 18 | 19 | 还有一个问题:Tarjan算法对于询问(X,Y),在DFS遍历时有着先后的顺序,如果Y后被遍历,那么刚好X与LCA(X,Y)同在一个集合,但此时Y并不与LCA(X,Y)在同一集合,那怎么知道Y到LCA(X,Y)这条路径的值呢? 20 | 21 | 这里有两种方法:一种是将每个节点的边的顺序反过来,再次DFS,则此时Y先被遍历。而更方便的是:我们可以在DFS回到LCA(X,Y)时再次询问Y,此时显然Y与LCA(X,Y)在同一集合,此时就可以回答询问(X,Y)了。 22 | -------------------------------------------------------------------------------- /POJ/poj3729.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ Monthly Contest – 2009.04.05: Facer’s string 2 | 3 | ## Summary 4 | 5 | 给出两个字符串S1,S2,长度不超过50000. 现定义一个S3: 6 | 7 | * S3是S1的一个子串 8 | * S3在S2中也出现 9 | * S3加上其在S1中的后继字符(若在最尾则加上空格字符)不能够在S2中出现. 10 | 11 | 问:S3有多少个? 12 | 13 | ## Solution 14 | 15 | 设f(k)为长度为k的字符串,且满足前两个条件.那么题目的最终答案为:f(k)-f(k+1). 16 | 17 | 使用RK字符串的Hash的方法可以解决这个问题解决.注意,由于有可能存在冲突,因此需要对每个字符串求出两个Hash值,提高命中率. 18 | -------------------------------------------------------------------------------- /POJ/poj3732.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # PKU Campus 2009 (POJ Monthly Contest – 2009.05.17): Paint Me Less 2 | ## Summary 3 | 4 | 在N*M的方阵里(1≤R≤4, 1≤C≤4),使用[0-19]的数字表示颜色,每次可以对一个颜色相同的连通块进行操作,将其颜色改变。问最少经过多少次改变能把整个方阵的颜色变成 0,要求输出方案。 5 | ## Solution 6 | 7 | 可以知道,最大的改变步数不会超过16,因此可以使用迭代加深的搜索方法来解决这个问题。但是,由于题目的规模很大,因此需要几个重要的剪枝: 8 | 9 | 1.每次dfs时只向后面的格子进行搜索,因为易证明每个格子最多只需要改变一次颜色就可以达到目标状态。 10 | 11 | 2.很重要的一个策略:每次将一个格子改变为另一种颜色时的选择。我们只可能将其改变为周围相邻的格子的颜色和0号颜色。也就是说,对于一 个格子,最多只可能尝试将其改变为5次颜色,而且能把其中重复的改变去掉,这样能够大量减少状态的生成。 12 | 13 | 3.设计一个估价函数,能够估计出当前状态到目标状态最小要经过的步长。这个对于迭代加深搜索来说异常重要,能够大量减少状态。在这个题目 中,我们可以知道,如果当前状态中方阵中有N种不为0的不同的颜色,那么要至少要经过N步才能到达目标状态,可以用这个来卡界。 14 | 15 | 4.不使用STL,速度提高十倍以上。 16 | 17 | 以下代码79ms AC,相当高效。 18 | -------------------------------------------------------------------------------- /POJ/poj3734.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ 3734 Blocks 2 | ## Summary 3 | 4 | 有一个长为N(1≤N≤10^9)的链条,给这个链子涂上R,G,B,Y四种颜色,其中R,G的链子的数目必须是偶数。问有多少种涂色方法。 5 | 6 | ## Solution 7 | 8 | 先列出递推式子,然后再使用矩阵快速幂解决。设f[n][0]表示长为n时,链条中R,G的数目均为偶数;f[n][1]表示长为n时,链条中R,G的数目一奇一偶;f[n][2]表示长为n时,链条中R,G的数目均为奇数,那么有如下转移: 9 |
10 | f[n+1][0]=2f[n][0]+f[n][1]
11 | f[n+1][1]=2f[n][0]+2f[n][1]+2f[n][2]
12 | f[n+1][2]=f[n][1]+2f[n][2]
13 | 
14 | 得出的矩阵就是 15 |
16 | 2 1 0
17 | 2 2 2
18 | 0 1 2
19 | 
20 | 求该矩阵的n次方,然后输出最左上角的元素即可。 21 | -------------------------------------------------------------------------------- /POJ/poj3734.cpp: -------------------------------------------------------------------------------- 1 | // POJ 3734 2 | // PKU Campus 2009 (POJ Monthly Contest – 2009.05.17): Blocks 3 | #include 4 | #include 5 | int len; 6 | typedef long long ll; 7 | #define N 3 8 | #define M 10007 9 | void matrix_mul(ll a[][N], ll b[][N]) { 10 | int i, j, k; 11 | ll x[N][N] = { 0 }; 12 | for (i = 0; i < len; i++) 13 | for (j = 0; j < len; j++) 14 | for (k = 0; k < len; k++) 15 | x[i][j] += a[i][k] * b[k][j]; 16 | for (i = 0; i < len; i++) 17 | for (j = 0; j < len; j++) 18 | a[i][j] = x[i][j] % M; 19 | } 20 | 21 | void matrix_power(ll a[][N], int exp) { 22 | ll x[N][N]; 23 | int i, j; 24 | if (exp == 0) { 25 | memset(x, 0, sizeof(x)); 26 | for (i = 0; i < len; i++) 27 | x[i][i] = 1; 28 | memcpy(a, x, sizeof(x)); 29 | return; 30 | } 31 | for (i = 0; i < len; i++) 32 | for (j = 0; j < len; j++) 33 | x[i][j] = a[i][j]; 34 | ll tp, n = 0; 35 | for (tp = 1; tp <= exp; tp *= 2, n++) 36 | ; 37 | for (n -= 2; n >= 0; n--) { 38 | matrix_mul(a, a); 39 | if ((1 << n) & exp) matrix_mul(a, x); 40 | } 41 | } 42 | int main() { 43 | //freopen("in.txt", "r", stdin); 44 | int T, e; 45 | scanf("%d", &T); 46 | len = 3; 47 | while (T--) { 48 | ll a[N][N] = { { 2, 1, 0 }, { 2, 2, 2 }, { 0, 1, 2 } }; 49 | scanf("%d", &e); 50 | matrix_power(a, e); 51 | printf("%lld\n", a[0][0]); 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /POJ/poj3739.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # POJ 3739 Special Squares 2 | ## Summary 3 | 给出平面上一些平行于X轴和Y轴的直线,以及一些点,问这些直线能组成多少个中间或边上包含点的正方形。 4 | ## Solution 5 | 6 | 直接统计。 7 | 8 | 使用二维数组,预处理出哪些地方有点,求和。 9 | 10 | 然后两两枚举Y方向的直线,将直线按直线间距离的差分类。 11 | 12 | 最后两两枚举X方向的直线,求出直线的差值,然后在Y方向的直线上寻找所有能够与之组成正方形的线对,然后看看里面有没有点。 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ACM-ICPC OJ Solution Code 2 | ======== 3 | ## Introduction 4 | 5 | My solution codes for popular Online Judge Systems, such as POJ, HDOJ, SGU and ACM-ICPC Live Archive. However, I am forgeting the algorithms which I used to solve these problems! 6 | 7 | I am going to organize the codes and solutions by contests. Some indexes page will be available so you can locate the problem quicker. 8 | 9 | Most of the reports were written in Chinese because most of them were written when I was a college students. However, you may find some useful comments in English in the codes. 10 | 11 | Please try to think and solve the problems before you refer my solutions. Good luck and enjoy these interesting problems! 12 | 13 | ## OJ Lists 14 | ### POJ 15 | Peking University JudgeOnline: http://poj.org/ 16 | 17 | ### ACM-ICPC Live Archive 18 | https://icpcarchive.ecs.baylor.edu/ 19 | 20 | ### SGU 21 | Saratov State University Online Contester: http://acm.sgu.ru/ 22 | 23 | ### HDU (HDOJ) 24 | Hangzhou Dianzi University Online Judge: http://acm.hdu.edu.cn/ 25 | -------------------------------------------------------------------------------- /SGU/110.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 110 Dungeon 2 | 3 | ## Summary 4 | 5 | 在一个三维立体空间上有N个球,从一个起点s向d方向发出一束光,问这束光在这些球之中如何反射,要求给出每次碰到的球的ID,如果反射次数大于 十,那么后面的都输出“etc.”。此外,如果光线与球面相切,那么仍认为光线与球“碰撞”了。 6 | 7 | ## Solution 8 | 9 | 题目的难点有两个:一是求直线和球的交点,二是求向量在球切面上的旋转。 10 | 11 | (1)处理第一个问题,可以使用解析几何的思想。 12 | 13 | 直线的参数方程为: 14 | l = p + t * v 15 | 其中,p为直线的一个点,v为直线的方向向量,t为参数。 16 | 17 | (2)球面的参数方程为: 18 | 19 | (u - v)2 = R2 20 | 其中,u为球面上的一个点,c为球心,R为半径。 21 | 22 | 要求交点,那么连理两个方程,将l代入圆的参数方程即可。这时问题就变成解一个一元二次方程。如果方程无解,那么说明球与直线没有交点。如 23 | 果解出来的参数t<0,必须忽略。对于有多个t,取t的最小值且t>0。 24 | -------------------------------------------------------------------------------- /SGU/131.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 131 Hardwood floor 2 | ## Summary 3 | 一个n\*m的棋盘上面,用1\*2和2\*2缺1角的骨牌完美覆盖之,问有多少种方案。规模:(n,m<=9) 4 | 5 | ## Solution 6 | 状态压缩DP。 7 | -------------------------------------------------------------------------------- /SGU/131.cpp: -------------------------------------------------------------------------------- 1 | // SGU 131 Hardwood floor 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | #define N 9 7 | long long f[2][1 << N]; 8 | int n, m, t; 9 | void dfs(int p, int s1, int s2, int b1, int b2) { 10 | if (p == m) { 11 | // When p == m, check whether b1 == 0 and b2 == 0 before counting. No piece could exceed the floors. 12 | if (!b1 && !b2) f[t][s1] += f[!t][s2]; 13 | return; 14 | } 15 | if (!b1 && !b2) { 16 | // Tiling 1 17 | dfs(p + 1, (s1 << 1) | 1, s2 << 1, 0, 0); 18 | // Tiling 2 19 | dfs(p + 1, (s1 << 1) | 1, s2 << 1, 1, 0); 20 | // Tiling 3 21 | dfs(p + 1, (s1 << 1) | 1, s2 << 1, 0, 1); 22 | } 23 | if (!b1) { 24 | // Tiling 4 25 | dfs(p + 1, (s1 << 1) | 1, ((s2 << 1) | 1) - b2, 1, 0); 26 | // Tiling 5 27 | dfs(p + 1, (s1 << 1) | 1, ((s2 << 1) | 1) - b2, 1, 1); 28 | } 29 | // Tiling 6 30 | if (!b2) dfs(p + 1, (s1 << 1) + b1, s2 << 1, 1, 1); 31 | // Tiling 7 32 | dfs(p + 1, (s1 << 1) + b1, ((s2 << 1) | 1) - b2, 0, 0); 33 | } 34 | int main() { 35 | memset(f, 0, sizeof(f)); 36 | scanf("%d%d", &n, &m); 37 | if (m > n) swap(n, m); 38 | f[0][(1 << m) - 1] = 1; 39 | t = 1; 40 | for (int i = 1; i <= n; i++, t = !t) { 41 | memset(f[t], 0, sizeof(f[t])); 42 | dfs(0, 0, 0, 0, 0); 43 | } 44 | printf("%lld\n", f[!t][(1 << m) - 1]); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /SGU/142.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 142 Keyword 2 | 3 | ## Summary 4 | 5 | 给出一个仅有a,b组成的字符串S,长度不超过500000。要求找出一个字符串SS,也是由a,b构成的,且此串不为S的任意一个子串,并且使其长度尽量短。 6 | 7 | ## Solution 8 | 9 | 给出的串长度为N=500000,而我们肯定目标串长度N`必定不超过20。因为220 \>500000。而长为500000的字符串中最多只有500000-20+1个长为20的字串。这就说明了,一个长为20的串,枚举其全排列组合,必定有不为S字串的串。因此我们只需要留意长为1-20的串。 10 | 11 | 使用二分法,每次二分一个目标长度mid,将S中所有长为mid的字串插入到Trie之中,然后在这个Trie中进行深搜,判断是否存在目标串即可。 12 | -------------------------------------------------------------------------------- /SGU/149.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 149 Computer Network 2 | 3 | ## Summary 4 | 给出一棵树,树上的边是带权的。然后询问每个节点与离他最远的那个点的距离。 5 | 6 | 题目的输入有点奇怪。其实输入n后,下面是第i+1(也就是2-n)顶点的父节点,第二个数字为那条边的边权。那么意味着1可以看作树的一个根。 7 | ## Solution 8 | 9 | 经典的Tree DP。使用四个数组记录:d1[]:当前节点,到其下最远的距离。 10 | p1[]:记录d1这个最优值是由哪个子树获得的。 11 | d2[]:当前节点,到其下次远的距离。其实这个次远不不一定是真正的次远。而是应该表达为:除了走最远的那棵子树意外,走其他子树而得到的最远距离。因此,这个次远值有可能和最远值相等。 12 | d3[]:当前节点,通过其父向上走能够达到的最远距离。 13 | 14 | 那么明显,对于一个节点,Max(d1[i], d3[i])就是答案。d1,d2的状态转移比较简单。根据定义,先算出一个节点的d1值,然后再去更新d2的值就可以了。 15 | 16 | d3的值可以在另一次dfs中完成。每个节点的d3的值都是通过父亲节点向下传的。设f为p的父节点,有 17 | ```c 18 | max(d, d2[x]) + G[x][i].d //p是d1[f]这个最优值所获得的子树 19 | max(d, d1[x]) + G[x][i].d //p不是d1[f]这个最优值所获得的子树 20 | ``` 21 | -------------------------------------------------------------------------------- /SGU/149.cpp: -------------------------------------------------------------------------------- 1 | // SGU 149 Computer Network 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define N 10005 8 | struct NODE { 9 | int p, d; 10 | NODE() { 11 | } 12 | NODE(int p, int d) : 13 | p(p), d(d) { 14 | } 15 | }; 16 | vector G[N]; 17 | int d1[N], d2[N], d3[N]; 18 | int best[N]; 19 | void dfs1(int x) { 20 | int i, p; 21 | d1[x] = d2[x] = 0; 22 | for (i = 0; i < (int) G[x].size(); i++) { 23 | p = G[x][i].p; 24 | dfs1(p); 25 | if (d1[x] < d1[p] + G[x][i].d) d1[x] = d1[p] + G[x][i].d, best[x] = p; 26 | } 27 | for (i = 0; i < (int) G[x].size(); i++) { 28 | p = G[x][i].p; 29 | if (best[x] == p) continue; 30 | if (d1[p] + G[x][i].d > d2[x]) d2[x] = d1[p] + G[x][i].d; 31 | } 32 | } 33 | 34 | void dfs2(int x, int d) { 35 | int i, p; 36 | d3[x] = d; 37 | for (i = 0; i < (int) G[x].size(); i++) { 38 | p = G[x][i].p; 39 | if (p == best[x]) dfs2(p, max(d, d2[x]) + G[x][i].d); 40 | else dfs2(p, max(d, d1[x]) + G[x][i].d); 41 | } 42 | } 43 | int main() { 44 | int n, i, x, d; 45 | scanf("%d", &n); 46 | for (i = 2; i <= n; i++) { 47 | scanf("%d%d", &x, &d); 48 | G[x].push_back(NODE(i, d)); 49 | } 50 | dfs1(1); 51 | dfs2(1, 0); 52 | for (i = 1; i <= n; i++) 53 | printf("%d\n", max(d1[i], d3[i])); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /SGU/174.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 177 Walls 2 | 3 | ## Solution 4 | 使用并查集+平衡树维护这个数据结构. 5 | 6 | 每次给出一个线段,在平衡树里面查找两个端点的id,如果不存在则分配新的id.两个端点的id分别为i1和i2,如果i1和i2在同一个并查集的子集里面,那么就证明连成了一个封闭的领土.否则将i1和i2并起来. 7 | 8 | 除了使用平衡树,还可以使用Hash,也可以先将所有的点的信息读入,然后排序,再二分查找. 9 | -------------------------------------------------------------------------------- /SGU/174.cpp: -------------------------------------------------------------------------------- 1 | // SGU 177 Walls 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | #define N 400005 7 | 8 | struct POINT { 9 | int x, y; 10 | bool operator <(const POINT &p) const { 11 | if (x != p.x) return x < p.x; 12 | return y < p.y; 13 | } 14 | void get() { 15 | scanf("%d%d", &x, &y); 16 | } 17 | }; 18 | 19 | // Union set 20 | int fa[N]; 21 | void setinit(int n) { 22 | for (int i = 0; i <= n; i++) 23 | fa[i] = i; 24 | } 25 | int find(int x) { 26 | if (fa[x] != x) fa[x] = find(fa[x]); 27 | return fa[x]; 28 | } 29 | 30 | void uniset(int x, int y) { 31 | fa[x] = y; 32 | } 33 | int id = 0; 34 | map ll; 35 | int main() { 36 | int n, i1, i2, ans = 1; 37 | POINT p1, p2; 38 | freopen("in.txt", "r", stdin); 39 | scanf("%d", &n); 40 | setinit(n * 2); 41 | while (n--) { 42 | p1.get(), p2.get(); 43 | if (ans == 1) { 44 | ll[p1] = id++, ll[p2] = id++; 45 | uniset(0, 1); 46 | } else { 47 | if (ll.find(p1) != ll.end()) i1 = ll[p1]; 48 | else { 49 | i1 = id; 50 | ll[p1] = id++; 51 | } 52 | if (ll.find(p2) != ll.end()) i2 = ll[p2]; 53 | else { 54 | i2 = id; 55 | ll[p2] = id++; 56 | } 57 | i1 = find(i1), i2 = find(i2); 58 | if (i1 == i2) { 59 | printf("%d\n", ans); 60 | return 0; 61 | } else uniset(i1, i2); 62 | } 63 | ans++; 64 | } 65 | printf("0\n"); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /SGU/177.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 177 Little Queens 2 | 3 | ## Solution 4 | 可以使用平面四叉线段树解决这个问题.四叉线段树是普通线段树的加强版,能够处理二维的平面问题. 5 | 6 | 这个问题的解决方法有很多,四叉树是通法,但是由于N不是很大,线段树的优势无法体现,因此效率不高,而且编程比较复杂.可以有如下解决方法: 7 | 8 | 1. 对每一个行都建立一个普通线段树进行处理.实际上是可以逐行统计的,这样就省去了二维线段树的编写. 9 | 2. 更简单的方法是:每行都记录一个next数组,next\[i\]意味着i->next\[i\]这一段是已经染过色了。从最后一个染色的矩形开始,依次染色,分别处理每一行,处理过(j,i)后,可以直接跳到(j,next\[i\]),中间的部分不再处理,然后,修改next数组。这样做的复杂度是 O(N^2\*log\*n),因为后者一般不超过5,所以可以看成常数。 10 | -------------------------------------------------------------------------------- /SGU/193.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 193 Chinese Girls' Amusement 2 | 3 | ## Solution 4 | 5 | 可以寻找规律的数学题. 6 | 7 | 1. 如果N是奇数,明显N/2就是答案. 8 | 2. 如果N是偶数,且N/2也偶数,那么N/2-1就是答案. 9 | 3. 否则N/2-2是答案. 10 | 11 | 题目给出的数字范围很大,因此需要使用高精度运算. 12 | -------------------------------------------------------------------------------- /SGU/222.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 142 Little Queens 2 | 3 | ## Solution 4 | 5 | 直接用公式即可:C(n, k)\*A(n, k).这个公式的含义是明显的,从棋盘中选出k行出来,放置车;然后再从k行的n个列中进行全排列,枚举车放置的列.当k>n时直接输出0即可. 6 | -------------------------------------------------------------------------------- /SGU/222.cpp: -------------------------------------------------------------------------------- 1 | // SGU 222 Little Rooks 2 | #include 3 | #include 4 | long long f(long long x) { 5 | long long ans = 1; 6 | while (x > 1) 7 | ans *= x--; 8 | return ans; 9 | } 10 | int main() { 11 | long long n, k, ans; 12 | scanf("%lld%lld", &n, &k); 13 | if (k > n) printf("0\n"); 14 | else { 15 | ans = f(n) / f(n - k); 16 | ans *= f(n) / f(k) / f(n - k); 17 | printf("%lld\n", ans); 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /SGU/224.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 142 Little Queens 2 | 3 | ## Solution 4 | 5 | N皇后求解的个数的问题,是使用回溯法搜索的应用典型问题. 6 | -------------------------------------------------------------------------------- /SGU/224.pas: -------------------------------------------------------------------------------- 1 | { SGU 297 Little Queens } 2 | program sgu224; 3 | var 4 | n, k :integer; 5 | ans:longint; 6 | vx, vy :array[1..10] of boolean; 7 | vo1: array[-10..10] of boolean; 8 | vo2: array[2..20] of boolean; 9 | procedure dfs(x,d:integer); 10 | var 11 | i, j:integer; 12 | begin 13 | if d = k then 14 | begin 15 | inc(ans); 16 | exit; 17 | end; 18 | if (d > n) or (n - x + 1+ d < k) then 19 | exit; 20 | for i := x to n do 21 | begin 22 | for j := 1 to n do 23 | begin 24 | if (vy[j] = true) or (vo1[i - j] = true) or (vo2[j + i] = true) then continue; 25 | vx[i] := true; vy[j] := true; vo1[i - j] := true; vo2[j + i] := true; 26 | dfs(i+1,d + 1); 27 | vx[i] := false; vy[j] := false; vo1[i - j] := false; vo2[j + i] := false; 28 | end; 29 | end; 30 | 31 | end; 32 | 33 | begin 34 | read(n, k); 35 | fillchar(vx, sizeof(vx), 0); 36 | fillchar(vy, sizeof(vy), 0); 37 | fillchar(vo1, sizeof(vo1), 0); 38 | fillchar(vo2, sizeof(vo2), 0); 39 | ans:= 0; 40 | dfs(1, 0); 41 | writeln(ans); 42 | end. 43 | -------------------------------------------------------------------------------- /SGU/297.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 299 Fair-play 2 | ## Solution 3 | 4 | 答案明显是将所有的数字加起来再对n求模。 5 | -------------------------------------------------------------------------------- /SGU/297.pas: -------------------------------------------------------------------------------- 1 | { SGU 297 Fair-play } 2 | program sgu297; 3 | var 4 | n, m, x, sum:longint; 5 | begin 6 | readln(n, m); 7 | sum := 0; 8 | repeat 9 | read(x); 10 | inc(sum, x); 11 | dec(m); 12 | until m = 0; 13 | writeln(sum mod n); 14 | end. 15 | -------------------------------------------------------------------------------- /SGU/299.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 299 Triangle 2 | ## Solution 3 | 4 | 先排序,然后再判断连续的三条边能否构成三角形。数据都很大,要使用高精度。 5 | -------------------------------------------------------------------------------- /SGU/332.Solution_CN.md: -------------------------------------------------------------------------------- 1 | # SGU 332 Largest Circle 2 | ## Summary 3 | 4 | 给出一个多边形,求出这个多边形的最大内接圆。多边形顶点数最大为10000。 5 | 6 | ## Solution 7 | 8 | 这种题目最典型的方法是二分一个内接圆的半径,然后使用将多边形的所有边向内推进R,然后用半平面交进行判断。如果推进后的边仍然能够围出一个多边形,则继续增大R,否则减少R。 9 | 10 | 虽然题目的规模很大,但是二分半径然后使用半平面交依然很高效,其原因是向内推进R不影响直线的极角序,因此使用zzy的半平面交算法时,极角序只需要排一次即可。每次二分出一个答案,求半平面交的扫描的复杂度都是线性的。因此这样做的总复杂度为(nlogn + nlogR)。 11 | 12 | 官方给出了一个nlogn的算法,但是未能实现: 13 | 14 | First, the exact solution, is as follows: try to 'compress' the initial polygon (i.e., let each side move at speed 1 towards the inside of the polygon). The answer to the problem is the moment of time when the polygon disappears. One can evaluate the moment of time when each side disappears (supposing its neighboring sides don't). So we find the side that disappears first, update the 'disappearing time' of its neighboring sides, and repeat the process until there're only 2 sides left. To keep this fast, you need to use a heap. 15 | -------------------------------------------------------------------------------- /World_Finals/2007.World_Finals/la3752.cpp: -------------------------------------------------------------------------------- 1 | // 2007 World Finals: Containers 2 | // ACM-ICPC Live Archive 3752 3 | 4 | #include 5 | #include 6 | #define N 1005 7 | char s[N]; 8 | int dp[N]; 9 | void solve() { 10 | int i, j, n, ans = 0; 11 | dp[0] = 1; 12 | n = strlen(s); 13 | for (i = 1; i < n; i++) { 14 | dp[i] = 1; 15 | for (j = 0; j < i; j++) { 16 | if (s[i] > s[j]) dp[i] = dp[i] > dp[j] + 1 ? dp[i] : dp[j] + 1; 17 | } 18 | } 19 | for (i = 0; i < n; i++) 20 | ans = ans > dp[i] ? ans : dp[i]; 21 | printf("%d\n", ans); 22 | } 23 | int main() { 24 | int ca = 1; 25 | while (scanf("%s", s) && s[0] != 'e') { 26 | printf("Case %d: ", ca++); 27 | solve(); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /World_Finals/2008.World_Finals/img/la4123_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/World_Finals/2008.World_Finals/img/la4123_img1.jpg -------------------------------------------------------------------------------- /World_Finals/2008.World_Finals/img/la4125_img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkkj/ACM-ICPC-OJ-Code/344b2c92f75b428d0241ba732c43de780d08df40/World_Finals/2008.World_Finals/img/la4125_img1.jpg -------------------------------------------------------------------------------- /World_Finals/2008.World_Finals/la4123.cpp: -------------------------------------------------------------------------------- 1 | // 2008 World Finals: Glenbow Museum 2 | // ACM-ICPC Live Archive 4123 3 | 4 | #include 5 | #include 6 | long long f(long long x) { 7 | return x * (x - 1) * (x - 2) * (x - 3) / 4 / 3 / 2; 8 | } 9 | int main() { 10 | long long n, ans; 11 | int ca = 1; 12 | while (scanf("%lld", &n) && n) { 13 | if (n % 2) ans = 0; 14 | else { 15 | n = (n + 4) / 2; 16 | ans = f(n) + f(n - 1); 17 | } 18 | printf("Case %d: %lld\n", ca++, ans); 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/4445_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 World Final: A Careful Approach 2 | 3 | ## Summary 4 | 有一个飞机场,有n (n <= 8)架飞机计划下降,飞机i可以在[ai,bi]这个时间区间内的一个时刻下降。为了使这些飞机安全下降,两架飞机下降时刻的间隔应该尽量大。问如何安排,使最小的时刻间隔尽量大。给出该时间间隔。 5 | 6 | ## Solution 7 | 可以先二分一个答案,把问题变成判定性问题。然后使用next_permutation枚举所有的排列,使用贪心判断一个排列是否成立。 8 | 9 | 注意要二分到浮点数,然后对答案四舍五入。 10 | -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/4446_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 World Final: My Bad 2 | 3 | ## Solution 4 | 由于题目规模很小,因此可以枚举每个电路门的错误状态,然后使用拓扑序正向搜一次,或记忆化搜索反向递归一次,求出所有输入的相应输出是否和题目给出的一致。 5 | 6 | 注意题目的描述,如果在没有任何电路门错误的情况下能够得到所有的正确输出,那么答案是No faults detected。对于每个电路门要记录其可能的错误数目。当且仅当有一个电路门有一种错误时,输出详细的错误信息。否则都是Unable to totally classify the failure。 7 | -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/4448_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 World Final: Conduit Packing 2 | 3 | ## Summary 4 | 5 | 给出平面上四个圆的直径,任意不重叠地放置这些圆,要求找出一个最小的圆包围这四个圆。求包围圆的半径。 6 | 7 | ## Solution 8 | 二分答案,把问题转化为判定性问题:给出一个圆,其半径为R,判断这个圆是否能够容纳给出的四个圆。 9 | 10 | 判定时,枚举这些圆的布置排列。首先,假设把包围圆的圆心放置在原点,直径最大的圆肯定与包围圆相切,那么先放置直径最大的圆,使其与包围 圆内接(为了方便计算,第一个内圆放在(0,-R+r)的位置)。然后搜索剩下的三个圆的放置:求当前圆的放置方案时,可以肯定有两种最优的方案: 11 | 12 | * 与包围圆内切,及和一个已放置的内圆外切 13 | * 与两个已经放置的内圆外切 14 | 15 | 求出符合条件的放置点,把当前圆放在这个点,然后再进行搜索。 16 | 17 | 把圆放置好后,判定这些圆是否相交。如果相交,那么就是这种搜索方案不成立。对于一个半径R,只要有一种搜索方案成立,那么这个R就是可行的。 18 | 19 | PS:求与已知的两个圆的相切的圆,实际上可以转化成两个圆的相交问题。而且每次求出来必定有两个符合条件的圆。 20 | -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/4450_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 World Final: Deer-Proof Fence 2 | 3 | ## Summary 4 | 平面上有n(n <= 8)棵树苗,有一些鹿会吃这些树苗。现在要用围栏把这些树苗围起来,使鹿与树苗保持margin的距离。问如何围这些栅栏,使栅栏的长度最小。可以把多棵树用同一个栅栏围起来。 5 | 6 | ## Solution 7 | 由于选取哪些点用一个栅栏没有规律,因此使用类似搜索的动态规划。因为数据规模很小,所以使用状态压缩思想,用dp[x]表示选取点集状态为x所求的最小的耗费。明显dp[x] = min_{i∈{x}} {dp[i] + calc(x-i)},其中i为x的一个二进制表示的一个子集,calc(st)能够计算出选择点集st放到同一个围栏的最小耗费,也就是点集的凸包的周长加上一个以margin为半径的圆的圆周。 8 | 9 | 预先使用calc函数算出所有点集的耗费后再进行DP即可。 10 | -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/4452_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 World Final: The Ministers' Major Mess 2 | 3 | ## Summary 4 | 5 | 有一个议会,有M个议员(M <= 500),这些议员就B(B <=100)个议案(Bill)进行投票。每个议员最多只能够投四票,表达Yes或者No。每个议案又有一个状态Yes和No。一个议员他被这个议会认可,当且仅当他有一半以上的投票符合议案的状态。问如何安排这些议案的Yes和No,使每个议员都被这个议会认可。如果没有方案则输出不可能。 6 | ## Solution 7 | 8 | 可以转化成一个2SAT问题:对于一个Bill,可以拆成两个点,Yes和No,对于Bill i,使用i×2表示该Bill为No,i×2+1表示该bill为yes(i从0开始)。由于一个议员的票必须要大于1/2正确才能Accept,因此如 果K=1,K=2,那么这个议员的票必须全部正确。如果K=3,K=4,那么这个议员的票最多只能够错一个。 9 | 10 | 因此,可以先对题目给出的条件构图,使用2SAT的方法判定是否可行。然后再枚举每个Bill的答案的状态,yes或no,再使用2SAT的方法判定是否可行。如果yes与no都可行,那么则输出?. 11 | -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/4453_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2009 World Final: Struts and Springs 2 | 3 | ## Solution 4 | 整个题目分为两个步骤。第一步是处理出窗口之间的父子关系。对于一个窗口,如果它的左上角在窗口X内,且X的宽最小,那么易得窗口X必定为当前窗口的父窗口。 5 | 6 | 第二步就是根据窗口之间的父子关系,递归计算各个窗口的大小。可以预先处理出每个窗口水平和垂直方向三个部件的原始大小。struct的大 小是不变的,无需更新。对于某个方向上的spring,只需知道父窗口在水平或垂直方向改变的大小△d,将△d按比例分摊给水平或垂直方向的各个 spring即可。再根据父窗口的绝对位置,就可以计算出子窗口的绝对位置。 7 | 8 | 由于题目说明每次得到的答案是整数,因此计算比例的时候要先乘后除,而且要注意使用long long。 9 | -------------------------------------------------------------------------------- /World_Finals/2009.World_Finals/la4445.cpp: -------------------------------------------------------------------------------- 1 | // 2009 World Finals: A Careful Approach 2 | // ACM-ICPC Live Archive 4445 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define N 10 9 | int n, b[N], e[N]; 10 | bool check(double t) { 11 | int i, idx[N]; 12 | for (i = 0; i < n; i++) 13 | idx[i] = i; 14 | do { 15 | int ok = 1; 16 | double cur = b[idx[0]]; 17 | for (i = 1; i < n && ok; i++) { 18 | cur += t; 19 | if(cur < b[idx[i]]) 20 | cur = b[idx[i]]; 21 | if(cur > e[idx[i]]) 22 | ok = 0; 23 | } 24 | if(ok)return 1; 25 | } while (next_permutation(idx, idx + n)); 26 | return 0; 27 | } 28 | void solve() { 29 | int i, ans; 30 | for (i = 0; i < n; i++) { 31 | scanf("%d%d", &b[i], &e[i]); 32 | b[i] *= 60, e[i] *= 60; 33 | } 34 | double l, r, mid; 35 | l = 0, r = 1441 * 60; 36 | while (l + 0.05 < r) { 37 | mid = (l + r) / 2.0; 38 | if (check(mid)) l = mid; 39 | else r = mid; 40 | } 41 | ans = (int) (mid + 0.5); 42 | printf("%d:%02d\n", ans / 60, ans % 60); 43 | } 44 | int main() { 45 | int ca = 1; 46 | while (scanf("%d", &n) && n) { 47 | printf("Case %d: ", ca++); 48 | solve(); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /World_Finals/2010.World_Finals/4787_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 World Finals: Tracking Bio-bots 2 | ## Solution 3 | 4 | 虽然题目的方格的范围很大,但是由于墙的数目只有1000个,因此产生的在X方向和Y方向坐标值不会超过2000个。 因此可以先离散化,然后把墙的情况填充到一个数组里面。如SAMPLE离散化后得到的图形如下: 5 | 6 |
 7 | 00000
 8 | 01110
 9 | 00000
10 | 00100
11 | 00000
12 | 00001
13 | 00000
14 | 
15 | 16 | 从右上角Exit点开始,使用简单的DP,就可以在两重循环里面判断出那些格子是Exit点可以到达的,那些是不可以的。最后再进行统计那些既不能 到达,也不是墙的格子的实际大小即可。 17 | 18 | 注意墙有可能堵住出口 19 | -------------------------------------------------------------------------------- /World_Finals/2010.World_Finals/4788_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2010 World Finals: Castles 2 | ## Solution 3 | 4 | 使用类似树形DP的方法+贪心。 5 | 6 | 先枚举一个起点,作为第一个攻打的城市,然后的问题就是:该节点下面的这么多个子树,应该按照一个怎样的顺序攻打。要解决这个问题就需要利 用贪心。 7 | 8 | 每个城市需要计算两个数字:到达并攻打该城市及其子树节点最少带需要的人数,以及子树总阵亡的人数,其中最少需要的人数必定大于等于阵亡的 人数。对于每个子树,求出这两个值,然后按照(子树最少带需要的人数-子树总阵亡的人数)从大到小排序,这个就是攻击子树的顺序。得到攻击顺序后,就可以 逆推,从最后一个城市开始推算出本节点的两个值。 9 | -------------------------------------------------------------------------------- /World_Finals/2011.World_Finals/5130_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2011 World Finals: Ancient Messages 2 | 3 | ## Solution 4 | 5 | 先使用floodfill,预处理出所有的字母以及空白,打上标记。然后对字母进行逐个统计即可。 6 | 7 | 注意要在字符矩阵两边留空,否则有可能会出错。 8 | -------------------------------------------------------------------------------- /World_Finals/2011.World_Finals/5138_Solution_CN.md: -------------------------------------------------------------------------------- 1 | # 2011 World Finals: Trash Removal 2 | 3 | ## Solution 4 | 5 | 首先要对凹多边形求凸包,然后对这个凸多边形进行求解。 6 | 7 | 明显,在最优的情况下,垃圾槽的左右两条边必定与多边形相接触。可以证明,垃圾槽的一边必定与多边形的一边贴合才能达到最优。由于题目的规模不大,基于上述结论,可以枚举多边形的边,求出该边贴合在垃圾槽上时垃圾槽的宽度。找出其中最小的值就是答案。 8 | 9 | 垃圾槽的一边与多边形的一边贴合达到最优的说明: 10 | 11 | 假设多边形有两个顶点A,B。线段AB的以A、B为垂足有两条垂线l1,l2,(l1,l2平行)如果l1,l2不与多边形其他部分相交, 那么l1,l2是其中的一个解。我们同时旋转l1,l2,使其保持平行,明显,如果此时l1,l2仍不与多边形其他部分相交,那么旋转的角度越 大,l1,l2之间的距离越短,答案最优。由于l1,l2不可能无限旋转,他们最终的旋转必定是有一边(l1或l2)卡在多边形的某条边上,与该边贴合。 此时旋转角度最大,达到l1贴合A或l2贴合B的情况下的局部最优。 12 | --------------------------------------------------------------------------------