ABC 045 C - たくさんの数式
qiitaの蟻本互換記事の問題。
s = "" def rec(i, word): if i == len(s): return eval("".join(word)) ans = 0 word.append('+') word.append(s[i]) ans += rec(i+1, word) word.pop() word.pop() word.append(s[i]) ans += rec(i+1, word) word.pop() return ans def main(): global s s = input() print(rec(1, [s[0]])) if __name__ == '__main__': main()
eval使ったやつ。eval使わなかったらめんどくさそうだなと思った。
AGC 013 A - Sorted Arrays
競プロ熱が高まってきたので、qiitaの記事のやつ進めることにした。 数列の切り出しができなかったのよね
def main(): n = int(input()) a = [int(i) for i in input().split()] ans = 0 i = 0 while i < n: # 右隣が同じにならないようにする while i+1 < n and a[i] == a[i+1]: i+=1 # i は n-1 で抜けてくるので、下には引っかからない # 右隣の数の方が大きかったら if i+1 < n and a[i] < a[i+1]: # 右隣の方が小さくなるまで、次に進める while i+1 < n and a[i] <= a[i+1]: i += 1 # 右隣の数の方が小さかったら elif i+1 < n and a[i] > a[i+1]: # 右隣の数が大きくなるまで、次に進める while i+1 < n and a[i] >= a[i+1]: i += 1 # a[i]まで切り取る ans += 1 # i をインクリメントして、新しい配列の先頭とする i += 1 print(ans) if __name__ == '__main__': main()
gnu as tips
OSのbootプロセスを見る日々です。 オペコードオペランドはパスで。
1.マクロ1
/* マクロの定義 */ .macro macro_name ... .macro macro_name # マクロの展開
2.マクロ2
#define three(sym) sym ## sym ## sym
gccで使うようなマクロの定義。
#include "xxx.h"
を使うなら、gccでアセンブルする。##で結合できる。関数みたいに定義できたりする。gccを使うときは拡張子は.Sにしないとダメっぽい。
3.ラベルジャンプ
jmp 1f 1: push %eax jmp 1b
ラベル名+f, ラベル名+b で前後どっちのラベルかを指定できる。forwardとbackwardっぽい。
サンプル
/* sample.h */ #define A 1 #if defined (A) #define LOCAL(sym) _ ## sym #define FUNCTION(x) .global LOCAL(x) ; LOCAL(x): #endif
.code32 #include "sample.h" FUNCTION(abc) push %eax 1: .macro sample push %eax push %ebx .endm sample jmp 1b jmp 1f 1: nop
sample.o: file format elf32-i386 Disassembly of section .text: 00000000 <_abc>: 0: 50 push %eax 1: 50 push %eax 2: 53 push %ebx 3: eb fc jmp 1 <_abc+0x1> 5: eb 00 jmp 7 <_abc+0x7> 7: 90 nop
IPLでセクタ読み込みエラー
OS自作入門をgasで書きなおしてみたいなぁって思って進めてたんだけど、セクター読み込みでエラーが出てた。
なんで読み込めないのかなぁって思って、調べてたら、ディスク番号が違かったらしい。
起動時に、%dlに起動したドライブ番号が入ってるらしいので、それを退避させておけばいいっぽい。qemuでドライブ番号って変えられるんかな。
ABC128 C Switches
出れなかったんだけど、AtCoderの解説動画が結構参考になったので、pythonで書く
数え上げ系すごく苦手なので、戒め兼補足。解説動画が少しわかりにくかったので。
問題概略。 ON/OFFスイッチが N 個と電球が M 個ある。それぞれのスイッチは複数の電球とランダムに接続されている。電球は、繋がっているスイッチのうちONになっているものの数が、偶奇どちらかの時(ランダム)、点灯する。それを決めるのは、P_i (1 ≦ i ≦ M)。全ての電球をつけるスイッチのパターンの数を求めよ。
解説では、bit全探索だった。N ≦ 10 なので、2 ^10 ≒ 10 ^3 なので十分。
まず、入力を表に接続表(隣接行列みたいなやつ)にする.
スイッチ番号\電球番号 | 0 | 1 | 2 |
---|---|---|---|
0 | 1 | 1 | 0 |
1 | 1 | 0 | 1 |
こんな感じにしたい。bit全探索にすると、実装が楽になるので、2 進数にする。この時上の表と 桁が反転することになる。
スイッチ番号\電球番号 | 2 1 0 |
---|---|
0 | 011 |
1 | 101 |
ここで、スイッチ 0 を押すと、それぞれの電球の押されているスイッチの数は
電球番号 | 2 | 1 | 0 |
---|---|---|---|
押されているスイッチの数 | 0 | 1 | 1 |
になる。 さらに、スイッチ 1 を押すと
電球番号 | 2 | 1 | 0 |
---|---|---|---|
押されているスイッチの数 | 1 | 1 | 2 |
こうなる。電球とスイッチが繋がっていない場合は、数は上がらず、スイッチを押すと、押したスイッチの接続表の行を足していく動作になる。
ここで、単純に押されているスイッチの数をそれぞれ 2 で割れば、あまりが出て、点灯しているかいないかがわかるが、単純に行を足すのではなく、排他的論理和をとれば、直接それぞれのあまりが出せて、実装が楽になる。
全探索の部分は、シフトを活かして、列挙する。1 が立っている桁と、スイッチのONが対応している具合に。
通った解答
def main(): n, m = [int(i) for i in input().split()] # a[i] には i 番目のスイッチの 電球との接続情報が入っている a = [0 for i in range(n)] for j in range(m): k, *switch = [int(i) for i in input().split()] for s in switch: a[s-1] |= (1 << j) p = int(("".join(reversed([i for i in input().split()]))), base=2) ans = 0 # bit全探索 for i in range(1<<n): t = 0 for j in range(n): if (i >> j & 1) == 1: t ^= a[j] if t == p: ans += 1 print(ans) if __name__ == '__main__': main()
ABC125 C GCD on BalckBoard
i 番目の要素だけを除いた全体のGCDを求めるという愚直な案を書いて当然TLEだったので供養。
def gcd(x, y): xx = 0; yy = 0 if x >= y: xx = x; yy = y else: xx = y; yy = x while yy > 0: xx, yy = yy, xx%yy return xx def main(): n = int(input()) a = [int(i) for i in input().split()] ans = 1 for i in range(n): tmp = -1 for j in range(n): if j == i: continue if tmp == -1: tmp = a[j] tmp = gcd(tmp, a[j]) ans = max(ans, tmp) print(ans) if __name__ == '__main__': main()
ユークリッドの互除法の計算量がO(log(min(A,B))なので、これだとO(n2log(min(A,B))となってTLE。
解答を見ると、結合則を使って、左右のを求めて、最後に計算。といった具合だろうか。
def gcd(x, y): xx = 0; yy = 0 if x >= y: xx = x; yy = y else: xx = y; yy = x while yy > 0: xx, yy = yy, xx%yy return xx def main(): n = int(input()) a = [int(i) for i in input().split()] ans = 1 # gcd の結合則を利用する(X, Y, Zがありgcd(gcd(x,y),z)==gcd(x,gcd(x, y))) l = [0 for i in range(n)] r = [0 for i in range(n+1)] for i in range(n-1): l[i+1] = gcd(l[i], a[i]) for i in range(n-1, -1, -1): r[i] = gcd(r[i+1],a[i]) for i in range(n): ans = max(ans, gcd(l[i], r[i+1])) print(ans) if __name__ == '__main__': main()
これでAC出た。 結合則を用いて左右から計算していく発想は出なかったなぁ。