2006Bの解答
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[ACM/ICPC]]&br;
&br;
&br;
[[2006Bの問題:http://www.acm-japan.org/past-icpc/domestic2006/contest/all_ja.html#section_B]]&br;
&br;
&br;
回答者:[[ほへい]]&br;
&br;
解法:区切り位置を変えて電車を前後に分割し、前後入れ替え・逆向き等を全検索。&br;
これまでに見つかったパターンと比較して、一致しなかったらスタックに追加&br;
最後にスタックの要素を数え上げてファイルに書き込む&br;
&br;
所要時間:80分&br;
&br;
速度:データセット瞬殺&br;
&br;
実行環境:PenM 1.6GHz 512M Win2000&br;
&br;
備考:コンセプトは『文字列の扱いに慣れよう』&br;
なんて無駄なことを…。って意見はなしの方向で。&br;
きれいなコードは他の人に任せたいです。&br;
&br;
#include <stdio.h>
#include <stdlib.h>
FILE *fp_in, *fp_out;
const char *f_source = "2006B_in.txt";
const char *f_answer = "2006B_out.txt";
typedef struct __Train {
struct __Train *prev, *next;
char boxes[73];
} Train;
Train start_train, end_train;
void initTrain(void); // 重複しないパターンを保存するスタックの初期化
void push(Train train); // スタックに要素を追加する
/* 文字を結合して、新しいパターンであれば、それを要素に持つ Train をスタックに追加する。 */
void append(const char *before, const char *after);
void reverse(char *string, int length); // 文字列を逆順にする。
void copy(char *copy_string, const char *source); // 文字列をコピーする
/* 電車をある部分で前と後ろに分割する。 */
void setBeforeAfter(const char *original, char *before, char *after, int length, int devide);
int isEqual(const char *string1, const char *string2); // 二つの文字列が等しいかを返す。
int isNewTrain(Train new_train); // 電車が新しいパターンであるかを返す。
void getAnswer(const char *original, int length); // データセット一つ分の動作を担当する。
int main(void)
{
int num_data;
fp_in = fopen(f_source, "r");
fp_out = fopen(f_answer, "w");
start_train.next = &end_train;
end_train.prev = &start_train;
fscanf(fp_in, "%d", &num_data);
for(; num_data > 0; num_data--) {
Train original;
int length = 0;
fscanf(fp_in, "%s", original.boxes);
while(1) {
if(original.boxes[length] != '\0') {
length++;
}
else break;
}
getAnswer(original.boxes, length);
initTrain();
}
fclose(fp_out);
fclose(fp_in);
return 0;
}
void getAnswer(const char *original, int length)
{
int i, answer = 0;
Train *temp_train;
for(i = 0; i < length; i++) {
char before[73] = {0}, after[73] = {0}, rev_after[73] = {0};
setBeforeAfter(original, before, after, length, i);
append(after, before);
copy(rev_after, after);
reverse(rev_after, length - i);
append(rev_after, before);
append(before, rev_after);
reverse(before, i);
append(before, after);
append(after, before);
append(before, rev_after);
append(rev_after, before);
}
temp_train = start_train.next;
while(temp_train != &end_train) {
answer++;
temp_train = temp_train->next;
}
fprintf(fp_out, "%d\n", answer);
}
void append(const char *before, const char *after)
{
Train create;
int i = 0, j = 0;
while(1) {
if(before[i] != '\0') {
create.boxes[i] = before[i];
i++;
}
else {
break;
}
}
while(1) {
if(after[j] != '\0') {
create.boxes[i] = after[j];
i++, j++;
}
else {
break;
}
}
create.boxes[i] = '\0';
if(isNewTrain(create)) {
push(create);
}
}
void setBeforeAfter(const char *original, char *before, char *after, int length, int devide)
{
int i, j;
for(i = 0; i < devide; i++) {
before[i] = original[i];
}
for(j = 0; i < length; i++, j++) {
after[j] = original[i];
}
}
void copy(char *copy_string, const char *source)
{
int i = 0;
while(1) {
if(source[i] == '\0') break;
copy_string[i] = source[i];
i++;
}
}
int isNewTrain(Train newTrain)
{
Train *temp_train = start_train.next;
while(temp_train != &end_train) {
if(isEqual(temp_train->boxes, newTrain.boxes)) return 0;
temp_train = temp_train->next;
}
return 1;
}
int isEqual(const char *string1, const char *string2)
{
int i = 0;
while(1) {
if(string1[i] == '\0') break;
if(string1[i] != string2[i]) return 0;
i++;
}
return 1;
}
void initTrain()
{
Train *temp_train = start_train.next;
while (temp_train != &end_train) {
Train *del_train = temp_train;
temp_train = temp_train->next;
free(del_train);
}
start_train.next = &end_train;
end_train.prev = &start_train;
}
void push(Train train)
{
Train *append = (Train*)malloc(sizeof(Train));
*append = train;
append->prev = end_train.prev;
append->next = &end_train;
end_train.prev = append;
append->prev->next = append;
}
void reverse(char *string, int length)
{
int i;
char temp;
for (i = 0; i < length / 2; i++) {
temp = string[i];
string[i] = string[length - i - 1];
string[length - i - 1] = temp;
}
}
終了行:
[[ACM/ICPC]]&br;
&br;
&br;
[[2006Bの問題:http://www.acm-japan.org/past-icpc/domestic2006/contest/all_ja.html#section_B]]&br;
&br;
&br;
回答者:[[ほへい]]&br;
&br;
解法:区切り位置を変えて電車を前後に分割し、前後入れ替え・逆向き等を全検索。&br;
これまでに見つかったパターンと比較して、一致しなかったらスタックに追加&br;
最後にスタックの要素を数え上げてファイルに書き込む&br;
&br;
所要時間:80分&br;
&br;
速度:データセット瞬殺&br;
&br;
実行環境:PenM 1.6GHz 512M Win2000&br;
&br;
備考:コンセプトは『文字列の扱いに慣れよう』&br;
なんて無駄なことを…。って意見はなしの方向で。&br;
きれいなコードは他の人に任せたいです。&br;
&br;
#include <stdio.h>
#include <stdlib.h>
FILE *fp_in, *fp_out;
const char *f_source = "2006B_in.txt";
const char *f_answer = "2006B_out.txt";
typedef struct __Train {
struct __Train *prev, *next;
char boxes[73];
} Train;
Train start_train, end_train;
void initTrain(void); // 重複しないパターンを保存するスタックの初期化
void push(Train train); // スタックに要素を追加する
/* 文字を結合して、新しいパターンであれば、それを要素に持つ Train をスタックに追加する。 */
void append(const char *before, const char *after);
void reverse(char *string, int length); // 文字列を逆順にする。
void copy(char *copy_string, const char *source); // 文字列をコピーする
/* 電車をある部分で前と後ろに分割する。 */
void setBeforeAfter(const char *original, char *before, char *after, int length, int devide);
int isEqual(const char *string1, const char *string2); // 二つの文字列が等しいかを返す。
int isNewTrain(Train new_train); // 電車が新しいパターンであるかを返す。
void getAnswer(const char *original, int length); // データセット一つ分の動作を担当する。
int main(void)
{
int num_data;
fp_in = fopen(f_source, "r");
fp_out = fopen(f_answer, "w");
start_train.next = &end_train;
end_train.prev = &start_train;
fscanf(fp_in, "%d", &num_data);
for(; num_data > 0; num_data--) {
Train original;
int length = 0;
fscanf(fp_in, "%s", original.boxes);
while(1) {
if(original.boxes[length] != '\0') {
length++;
}
else break;
}
getAnswer(original.boxes, length);
initTrain();
}
fclose(fp_out);
fclose(fp_in);
return 0;
}
void getAnswer(const char *original, int length)
{
int i, answer = 0;
Train *temp_train;
for(i = 0; i < length; i++) {
char before[73] = {0}, after[73] = {0}, rev_after[73] = {0};
setBeforeAfter(original, before, after, length, i);
append(after, before);
copy(rev_after, after);
reverse(rev_after, length - i);
append(rev_after, before);
append(before, rev_after);
reverse(before, i);
append(before, after);
append(after, before);
append(before, rev_after);
append(rev_after, before);
}
temp_train = start_train.next;
while(temp_train != &end_train) {
answer++;
temp_train = temp_train->next;
}
fprintf(fp_out, "%d\n", answer);
}
void append(const char *before, const char *after)
{
Train create;
int i = 0, j = 0;
while(1) {
if(before[i] != '\0') {
create.boxes[i] = before[i];
i++;
}
else {
break;
}
}
while(1) {
if(after[j] != '\0') {
create.boxes[i] = after[j];
i++, j++;
}
else {
break;
}
}
create.boxes[i] = '\0';
if(isNewTrain(create)) {
push(create);
}
}
void setBeforeAfter(const char *original, char *before, char *after, int length, int devide)
{
int i, j;
for(i = 0; i < devide; i++) {
before[i] = original[i];
}
for(j = 0; i < length; i++, j++) {
after[j] = original[i];
}
}
void copy(char *copy_string, const char *source)
{
int i = 0;
while(1) {
if(source[i] == '\0') break;
copy_string[i] = source[i];
i++;
}
}
int isNewTrain(Train newTrain)
{
Train *temp_train = start_train.next;
while(temp_train != &end_train) {
if(isEqual(temp_train->boxes, newTrain.boxes)) return 0;
temp_train = temp_train->next;
}
return 1;
}
int isEqual(const char *string1, const char *string2)
{
int i = 0;
while(1) {
if(string1[i] == '\0') break;
if(string1[i] != string2[i]) return 0;
i++;
}
return 1;
}
void initTrain()
{
Train *temp_train = start_train.next;
while (temp_train != &end_train) {
Train *del_train = temp_train;
temp_train = temp_train->next;
free(del_train);
}
start_train.next = &end_train;
end_train.prev = &start_train;
}
void push(Train train)
{
Train *append = (Train*)malloc(sizeof(Train));
*append = train;
append->prev = end_train.prev;
append->next = &end_train;
end_train.prev = append;
append->prev->next = append;
}
void reverse(char *string, int length)
{
int i;
char temp;
for (i = 0; i < length / 2; i++) {
temp = string[i];
string[i] = string[length - i - 1];
string[length - i - 1] = temp;
}
}
ページ名: