1.おつり AOJ0521
#include<iostream> #include<algorithm> using namespace std; #define INF ( 1 << 30 ) int main(){ int dp[1000],tmp[]={500,100,50,10,5,1},n; fill_n(dp,1000,INF); dp[0] = 0; for(int i = 0 ; i < 1000 ; i++ ){ for(int j = 0 ; j < 6 ; j++ ){ if(i - tmp[j] >= 0) dp[i] = min(dp[i],dp[i-tmp[j]]+1); } } while(cin >> n , n) cout << dp[1000-n] << endl; }なんかDPで解きたくなったので解いた。
2.JOI and IOI AOJ0522
#include<iostream> #include<string> using namespace std; int main(){ string s; while(cin >> s){ int joi = 0, ioi = 0; for(int i = 2 ; i < s.size() ; i++ ){ if(s.substr(i-2,3) == "JOI") joi++; else if(s.substr(i-2,3) == "IOI") ioi++; } cout << joi << endl << ioi << endl; } }substrで良い感じに抜き出してやった。
問題3.カードゲーム AOJ0523
#include<iostream> #include<algorithm> #include<queue> using namespace std; int main(){ int n, use[201], now, ban; while(cin >> n , n){ priority_queue<int,vector<int>,greater<int> > TaHa[2]; queue<int> tmp; fill_n(use,201,false),now = 0,ban = 0; for(int i = 0 ; i < n ; i++ ){ int card; cin >> card; use[card] = true; TaHa[0].push(card); } for(int i = 1 ; i <= 2*n ; i++) if(!use[i]) TaHa[1].push(i); while(!TaHa[0].empty() && !TaHa[1].empty()){ while(!TaHa[ban].empty() && now >= TaHa[ban].top()){ tmp.push(TaHa[ban].top()); TaHa[ban].pop(); } if(!TaHa[ban].empty()) now = TaHa[ban].top() , TaHa[ban].pop(); else now = 0; while(!tmp.empty()) TaHa[ban].push(tmp.front()) , tmp.pop(); ban ^= 1; } cout << TaHa[1].size() << endl << TaHa[0].size() << endl; } }優先度付きキューで解いた。デフォルトが降順になっていることに気付かずバグらせた。
priority_queueは降順。覚えたい(戒め)
問題4.星座探し AOJ0524
#include<iostream> #include<algorithm> #include<map> using namespace std; #define fr first #define sc second typedef pair< int , int > Pt; int m, n; bool serach( Pt *a, Pt *b, int& x,int& y){ for(int j = 1 ; j < m ; j++ ){ if(!binary_search(b,b+n,Pt(a[j].fr+x,a[j].sc+y))) return false; } return true; } int main(){ while(cin >> m , m){ Pt M[m]; for(int i = 0 ; i < m ; i++ ) cin >> M[i].fr >> M[i].sc; cin >> n; Pt D[n]; for(int i = 0 ; i < n ; i++ ) cin >> D[i].fr >> D[i].sc; sort(D,D+n); for(int i = 0 ; i < n ; i++ ){ int x = D[i].fr - M[0].fr , y = D[i].sc - M[0].sc; if(serach(M,D,x,y)){ cout << x << " " << y << endl; break; } } } }2分探索すれば早く探せるんじゃね的な考え方。
STL用意されてて良い。
問題5.おせんべい AOJ0525
#include<iostream> #include<algorithm> using namespace std; int main(){ int h,w; bool mas[10][10000]; while( cin >> h >> w , h ){ for(int i = 0 ; i < h ; i++ ){ for(int j = 0 ; j < w ; j++ ){ cin >> mas[i][j]; } } int ans = 0; for(int i = 0 ; i < (1 << h) ; i++ ){ int sum = 0; for(int j = 0 ; j < w ; j++ ){ int cnt = 0; for(int k = 0 ; k < h ; k++ ){ cnt += mas[k][j]^(i>>k&1); } sum += max( h - cnt , cnt ); } ans = max( sum , ans ); } cout << ans << endl; } }行の制約10じゃん。やったね!
裏返すパターンを全通り試すしか無い。ちょっと端折った。
問題6.船旅 AOJ0526
#include<iostream> #include<algorithm> using namespace std; #define INF ( 1 << 26 ) int main(){ int n,m,DATA[101][101]; while(cin >> n >> m , n){ fill_n(DATA[0],101 * 101,INF); for(int i = 0 ; i < 101 ; i++ ) DATA[i][i] = 0; while(m--){ int s, a, b, c; cin >> s >> a >> b; if(s){ cin >> c; if(DATA[a][b] > c){ DATA[a][b] = DATA[b][a] = c; for(int j = 1 ; j <= n ; j++){ for(int k = 1 ; k <= n ; k++){ DATA[j][k] = min(DATA[j][k] , DATA[j][a] + DATA[a][k]); DATA[j][k] = DATA[k][j] = min(DATA[j][k] , DATA[j][b] + DATA[b][k]); } } } }else cout << (DATA[a][b] == INF ? -1 : DATA[a][b]) << endl; } } }普通にWFやるといっちゃうので更新された所だけを更新する。O(n^2)くらいに出来る。
0 件のコメント:
コメントを投稿