Particle

競技プログラミングについての雑記

AOJ

AOJ 0509: Sheets

AOJ

最大値の伝播で解くのは難しそうだったから、累積和で解きました。 少し枝刈りしましたが遅いです。 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int g[10003][10003]; int n,r; int main(){ while(scanf("%d%d",&n,&r),n){ memset(g,0,sizeof(g)); in</algorithm></cstring></cstdio>…

AOJ 0525: Osenbei

AOJ

Rが小さいので、行単位でひっくり返すのは全て試します。 列は自由にひっくり返すことができるため、表になっているものの個数か裏になっているものの個数の内大きい方を使えば良いです。 数えるのにO(RC)かかるので、全体ではO(RC・2^R)になります。 #include<cstdio></cstdio>…

AOJ 0524: Searching Constellation

AOJ

星座にある星(固定しておく)から写真にある星までのベクトルを考えれば、並行移動の仕方はn通り あることが分かります。n通り全て試すためには、1通り試すのにO(m+n)やO(mlogn)程度で良いです。辞書順にソートしておくことで、O(n^2+mn)で解くことができます…

AOJ 0522: JOI and IOI

AOJ

文字列から"JOI"と"IOI"を検索する 2文字目と3文字めが共通しているので、1文字目は後で考えると少し速くなりそうです。 #include<iostream> #include<string> using namespace std; string s; int main(){ while(cin>>s){ int a=0,b=0; for(int i=1,l=s.size()-1;i</string></iostream>

AOJ 0523: Card Game

AOJ

太郎が持っている:1 花子が持っている:0 残ってない:-1のようにすると、配列1つと単純なループで解くことができます。(入出力も簡単) #include<iostream> #include<cstring> using namespace std; int card[200]; int main(){ int n; while(cin>>n,n){ memset(card,0,sizeof(car</cstring></iostream>…

AOJ 0520: Status of Lightest Mobile

AOJ

メモ化再帰で解きました。 順番にモビールを選び、そこから下のモビールの重さ(の最小値)を再帰的に求めます。 重さ * 長さ = モーメント なので、両方のモーメントを求めて、整数倍(最小公倍数を求める)し釣り合わせます。 重さ = モーメント / 長さ で、重…

AOJ 0518: The Oldest Site

AOJ

点A(a,b)と点B(c,d)があるとき、a A,Bを探すときは、入力された順に辿って行き、正方形ができているか調べるときは、辿らずに直接調べることで、O(n^2)になります。(全部辿るとO(n^4)になる) #include<cstdio> #include<cstring> using namespace std; int x[3000],y[3000],n,</cstring></cstdio>…

AOJ 0517: Longest Steps

AOJ

しゃくとり法で数えます。 0 2 3...n のときに、変な動作をしますが、撃墜はされません(他にコーナーケースがあるかもしれないけど、ACはできました) #include <algorithm> #include <iostream> #include <cstdio> #include <cstring> using namespace std; bool card[100020]; int n,k; int main()</cstring></cstdio></iostream></algorithm>…

AOJ 0515: School Road

AOJ

DPの基本的な問題。メモ化再帰でも、普通の再帰でも、全探索でも解けるらしい。 ある点に行くのに、左か下から行かなければならないというだけ。 #include<iostream> #include<cstring> using namespace std; int dp[16][16]; int main(){ int a,b,n; while(cin>>a>>b,a||b){ ci</cstring></iostream>…

AOJ 0503: Cup

AOJ

再帰する式を作れれば解けます。右シフトすると一番小さいカップが消えてくれて、他のカップが1つづつ小さくなります。 ステップをトレースする解法が想定解らしいですが、集合で解く方が楽です(トレースしようとして失敗しました) #include <algorithm> #include <iostream> usin</iostream></algorithm>…

AOJ 0561: Books

AOJ

ジャンル毎にx冊売った時の合計金額を前計算しておく。 普通にナップサック問題を解けば、解けます。実際には可能かもしれませんが、1次元配列ではDPできませんでした。 #include <algorithm> #include <cstdio> #include <vector> #include <functional> using namespace std; vector<int> books[10]; ve</int></functional></vector></cstdio></algorithm>…

AOJ 0105: Book Index

AOJ

vector を使い、ソートします。 vector<pair<string,vector<int> > > data; map<string,int> sf; int main(){ string s; int a,k = 0; while(cin>>s>>a){ if(!sf.count(s)){ sf[s] = k++; data.push_back(make_pair(s,vector<int> ())); } data[sf[s]].second.push_back(a); } sort(data.begin(),data.</int></string,int></pair<string,vector<int>…

AOJ 0508: String With Rings

AOJ

"嘘枝刈り"+DFS 適当に次数の小さいものを採用するようにしたら、何故か通りました。 #include <algorithm> #include <cstdio> #include <vector> using namespace std; int v[100]; vector<int> g[100]; inline int dfs(int x){ int ans = 0; for(int i = 0,l = g[x].size(); i < l; i++){ i</int></vector></cstdio></algorithm>…

AOJ 570: Zig-Zag Numbers

AOJ

動的計画法を使ってときました。問題の設定では1以上のものだけがZig-Zag数になるらしいですが、0以上にしても同じです。 const int mod = 10000; int M,len,dp[510][510][10][2][3]; /*dp[a][b][c][d][e] a:左からa桁目 b:剰余 c:一番右の数字 d:与えられた…

AOJ 507: Square

AOJ

問題文略模範解答では、再帰を使って解くらしいです。 最初に積み上げて置き、右側からブロックを一旦取り去って、次の状態にすることを繰り返してみました。 vectorを使ってるので(更に、push_back()とpop_back()を多用している)速くはないです。 #include <cstdio></cstdio>…

AOJ 505: Questionnaire

AOJ

ソート。INFから引いていけば簡単になります。 int main(){ int n,m; while(cin>>n>>m,n||m){ pair<int,int> p[100]; for(int i = 0; i < m; i++){ p[i].first = 2000; p[i].second = i+1;//INF = 2000 } for(int i = 0 ; i < n; i++){ for(int j = 0; j < m; j++){ i</int,int>…

AOJ 0574: Nails

AOJ

最大値の伝播です。正方形型にメモリを確保してしまうと、半分くらい無駄になってMLEしてしまうので、三角形にします。(こんな感じに) (-1, 0) ( 0, 0) ( 0, 1) ( 1, 0) ( 1, 1) ( 1, 2) ( 2, 0) ( 2, 1) ( 2, 2) ( 2, 3) ...この図で、輪ゴムにかかる可能性…

AOJ 0093: Leap Year

AOJ

出力に気をつけるのと、前計算するだけ。少しだけ短く書く場合は、 if(!(i%400) || i%100 && !(i%4)) leap[i]++; とする。 int leap[3000]; int main(){ for(int i = 1; i < 3000; i++){ if(i%400 == 0) leap[i] = 1; if(i%100 == 0) leap[i] -= 1; if(i%4 =…

AOJ 0089: The Shortest Path on A Rhombic Path

AOJ

入力してDPをします。上・下から真ん中までそれぞれ計算していって、上下の和が最大になるものを出力します。分からない場合は、まずは上半分だけについて考えてみましょう。(Project Euler に上半分だけの問題があったと思います。) int data[110][60],dp1[…

AOJ 0070: Combination of Number Sequences

AOJ

next_permutation()使って、DP。 重複して数えてるから、重複した回数((10-n)!回)で割ってあげる。本当は重複しないで数えたいところだが、これでもそんなに遅くないので妥協した。 int num[10]; long fact[10],dp[10][331];//和が331以上になることはない。…

AOJ 0056: Goldbach's Conjecture

AOJ

できるだけ、実行時間を短くしてみようとしました。コードも少しだけ短めにしました。 偶数を除いて普通にエラトステネスの篩を使って、(素数+素数)を全部計算しただけですが、可読性のことは全く考えていません。ごめんなさい。あと、if文って結構時間が掛…

AOJ 0054: Sum of Nth decimal places

AOJ

愚直に(10倍するだけで剰余を取らなかったり、double型を使ったりして)解こうとすると、精度が足りなかったり、オーバーフローするから、10倍しながら関係無い部分(整数部)を捨てていく。 int main(){ int a,b,n; while(cin>>a>>b>>n){ int ans = 0; a %= b;…

AOJ 0041: Expression

AOJ

適当にコードを短くしましょう。数字の並べ方:4!通り 演算子のつけ方:3(種類) ^ 3(場所) 通り 括弧のつけ方:5(4)通りで全部で9720(7776)通りなので、無駄が多いけど一瞬です。書くのは一瞬ではないですが、これで妥協しました。括弧のつけ方を1通り見落と…

AOJ 2332: Space-Time Sugoroku Road

AOJ

Problem 3: 時空のスゴロク・ロード全てのマスに対して、暫定の最短距離を求めるのを繰り返した。蟻本でこんな感じのアルゴリズムを見た記憶がある。たどり着く場所と、そこへの最短距離だけ分かればいい気がするけど、これでも通った。 int p[100000],d[100…

AOJ 0551: Icicles

AOJ

つらら汚いです。 やるだけで、実装が(自分にとっては)難しい問題だと思ったけど、考える問題らしい。余裕があるときに解きなおしたい。 long使う必要なかったかも。面倒臭いから全部longにしちゃったけど。 long n,l,ice[100002],ict[100002],icf[100002],i…

AOJ 0100: Sale Result

AOJ

やるだけ。入力の順番(ID)を覚えるだけ using namespace std; typedef long long ll; ll em[4000]; int flag[4000]; int main(){ int n; while(true){ int id,p,q; cin >> n; if(!n) return 0; for(int i = 0; i < n; i++){ cin>>id>>p>>q; em[id-1] += (ll)…

AOJ 0114: Electro-Fly

AOJ

解けてないです1 == a^n mod m (^はXORじゃないほう)となる最小のnを求める問題だと思う。 このコードを提出してみたら、遅すぎって怒られた。1.18秒から0.18秒減らさないといけない。 *1もしかすると最小公倍数をもっと効率良く求められるのかもしれない。 …