ポインタと配列
char str[100];
scanf("%s", &str);
で読み込んでいるソースがあって
「あれ?&strでもいいんだっけ?」と思いまして、実際&strとstrの違いをプログラムしてみたところ、
二つとも同じアドレスをさしていました('A`)マジカヨ
あんまりこういう使い方はしたことがなかったので改めて調べてみると
&str → char型配列の先頭へのポインタ
str → char型配列の先頭要素へのポインタ
であることが判明。さしてるところは同じだけど、ポインタの型が違うんだね~!多分納得!
&strが”char (*)[100]”型で、strが”char *”型になる訳ですよ!
なるほどねー
str+1ですすむアドレスは1バイト分
&str+1ですすむアドレスは100バイト分
scanf()の引数として&strをつかうのは別に大丈夫みたいだけど、一次元配列を引数に持つような関数だと多分警告とかエラーが出ると思うな。型自体が違う訳だし。
C言語ではよくポインタでつまづくとかいいますけど、僕の知り合いもかなりつまづいてました。その人のソースの修正をよくやっていたのですが、もう、正直、何度投げ出そうかと思ったかorz
デブンキー一家の大活躍
高校生がやるやつなのにね
ハイパー恥さらしタイム!はっじまっるよー!
プリム法で解を求めていたソースがあったので、こちらはクラスカル法で解いてみる事に
いかソース
001: #include
002: #include
003:
004: typedef struct {
005: int father;
006: } NODE;
007:
008: typedef struct {
009: int node1;
010: int node2;
011: int cost;
012: } ARC;
013:
014: NODE node[100];
015: ARC arc[5000];
016: int n, m;
017:
018: int read_data(void);
019: int kruskal(void);
020: int cmp(const void *a, const void *b);
021:
022: int main(void)
023: {
024: while (read_data()) {
025: qsort(arc, m, sizeof(ARC), cmp);
026: printf("%d\n", kruskal());
027: }
028:
029: return 0;
030: }
031:
032: int read_data(void)
033: {
034: int i;
035:
036: scanf("%d %d", &n, &m);
037: if (n == 0 && m == 0)
038: return 0;
039:
040: for (i = 0;i < m;i++)
041: scanf("%d %d %d", &arc[i].node1, &arc[i].node2, &arc[i].cost);
042: return 1;
043: }
044:
045: int cmp(const void *a, const void *b)
046: {
047: ARC arc1 = *(ARC*)a;
048: ARC arc2 = *(ARC*)b;
049:
050: return (arc1.cost - arc2.cost);
051: }
052:
053: int kruskal(void)
054: {
055: int i, total_cost, u, v;
056:
057: for (i = 0;i < n;i++)
058: node[i].father = i;
059: total_cost = 0;
060:
061: for (i = 0;i < m;i++) {
062: u = arc[i].node1;
063: v = arc[i].node2;
064:
065: while (u != node[u].father)
066: u = node[u].father;
067: while (v != node[v].father)
068: v = node[v].father;
069: if (u != v) {
070: node[u].father = v;
071: total_cost += arc[i].cost;
072: }
073: }
074:
075: return total_cost;
076: }
まぁ、プリム法でやってた人は40行くらいだったけどねorz
ポケットモンスターDP
ポケットモンスターダイナミックプログラミング
ごめんね、お兄さんポケモンの話はしないからごめんね動的計画法の話するからごめんね
ポケモン緑ではいろんなバグを使ってロム1つで全部のポケモン集めました
さて、プログラミングをする上では重要な問題解決法。その1つが動的計画法。
動的計画法とは、問題をいくつかの部分問題に分割して解くというアイデアに加えて、解をもとめた部分問題については解を記録し、同じ部分問題がでたときにその記録しておいた解を再利用する事により、再計算の時間を節約する手法である。
くちでゆーのはちょーかんたん
こういう抽象的な方法を現実問題に対応できるか否かは、その人の技量によります
もちろん僕はその技量があまり無い方ですがorz
今日はpartition problemの問題をやっていたのですが、まぁ、わかるようで、わからないというorz
partition problemはNP困難クラスに属するはずなので、計算量はすぐに青天井
例えば、
1 2 5 9 3 4
という数列において、並び方は変えないで
1 2 | 5 9 | 3 4
のように3つのグループに分けたときに、各グループの和が近くなるようにしなさいという感じ。
上のだと3と14と7ですが
1 2 5 | 9 | 3 4
とすると8、9、7で近くなったねーってなります(多分コレが最適解)
まぁ、ソースには出来なかったんだけど
なんかもう、自分の能力にがっかりする。
リーマン
リーマン・ブラザーズよりも
サラリーマンかリーマン予想が先に出てくる
別に経済に詳しい訳ではござんせんが、リーマンブラザーズが破綻して結構世界に影響が出てるみたいです。まぁ、経済とかぜんっぜんわかんないけど(笑)
工学と経済とを絡めるっつーと
金融工学とかかしら?
でもぶっちゃけ、そういうののプロって文系出身でもブラックショールズ方程式とか普通に使えちゃうんでしょうねぇ~
新書で金融工学についての本を読んだ事がありますが、あれで飯食べていける人は凄いと思う。