質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

213閲覧

ABC111のCを解きたい

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

1グッド

1クリップ

投稿2019/05/06 04:39

編集2019/05/06 05:01

前提・実現したいこと

https://atcoder.jp/contests/abc111/tasks/arc103_a
この問題をときたいです。
youtubeの解説放送は以下の動画のおおよそ26:27~です
https://www.youtube.com/watch?v=fYS-rAUSD5o&t=1927s

※C言語の文法がわからないとかではないです

発生している問題・エラーメッセージ

エラーは出ません。 サンプル以外のテストケース全てで間違いとされます。 テストケースがわからないので、こういうときにこのコードだとまずいよ というケースを教えていただけると幸いです。 シンプルにおかしいところでも構いません。

該当のソースコード

#include<stdio.h> #include<stdlib.h> int frequency(int idx, int n, int* pv, int Arr[][2]){ int tmp = pv[0]; int idxDarr = 0; int cnt = 0; while(idx < n){ if(tmp != pv[idx]){ idxDarr++; cnt = 1; Arr[idxDarr][0] = pv[idx]; Arr[idxDarr][1] = cnt; tmp = pv[idx]; }else{ Arr[idxDarr][0] = pv[idx]; cnt++; Arr[idxDarr][1] = cnt; } idx += 2; } if(idx == 0) return 0; else return 1; } int compDown(const void* a, const void* b){ int* pa = (int*)a; int* pb = (int*)b; return *(pb+1) - *(pa+1); } int main(void){ int n; scanf("%d", &n); int v[n]; for(int i = 0; i < n; i++){scanf("%d", &v[i]);} int oddTrg, evenTrg; int oddArr[n/2][2]; int evenArr[n/2][2]; for(int i = 0; i < n/2; i++){for(int j = 0; j < 2; j++){oddArr[i][j] = 0;}} for(int i = 0; i < n/2; i++){for(int j = 0; j < 2; j++){evenArr[i][j] = 0;}} //奇数番目、偶数番目それぞれの、数字とその個数の二次元配列をつくる int oddNum = frequency(0, n, v, oddArr); int evenNum = frequency(1, n, v, evenArr); //個数の大きい順に並び替える qsort(oddArr, n/2, 2*sizeof(int), compDown); qsort(evenArr, n/2, 2*sizeof(int), compDown); //並び替えれてるかのチェックに使う /*for(int i = 0; i < n/2; i++){for(int j = 0; j < 2; j++){printf("%d ", oddArr[i][j]);}printf("\n");} printf("----------\n"); for(int i = 0; i < n/2; i++){for(int j = 0; j < 2; j++){printf("%d ", evenArr[i][j]);}printf("\n");}*/ int ans = -1;; //数字の種類が1種類の時の処理も書かないといけなさそう if(oddNum == 0 && evenNum == 0){ if(oddArr[0][0] == evenArr[0][0]){ans = n/2;} else{ans = 0;} } else if((oddNum == 1) && (evenNum == 0)){ //ans = n/2; if(oddArr[0][0] == evenArr[0][0]){ans = n/2 - oddArr[1][1];} else{ans = n/2 - oddArr[0][1];} } else if((oddNum == 0) && (evenNum == 1)){ //ans = n/2; if(oddArr[0][0] == evenArr[0][0]){ans = n/2 - evenArr[1][1];} else{ans = n/2 - evenArr[0][1];} } //数字の種類が奇数番目偶数番目共に2種類以上の時用の処理 if(ans == -1){ if(oddArr[0][0] != evenArr[0][0]){ ans = n - (oddArr[0][1]+evenArr[0][1]); } else{ if(oddArr[0][1] > evenArr[0][1]){ ans = n - (oddArr[0][1] + evenArr[1][1]); } else if(oddArr[0][1] == evenArr[0][1]){ if(oddArr[1][1] >= evenArr[1][1]){ ans = n - (oddArr[1][1] + evenArr[0][1]); }else{ ans = n - (oddArr[0][1] + evenArr[1][1]); } } else{ ans = n - (oddArr[1][1]+evenArr[0][1]); } } } printf("%d\n", ans); return 0; }

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

frequency関数に2点問題があります。

  1. 連続していないと同一数値とみなさない

1 x 3 x 1 x => [[1,1],[3,3],[1,1]]

  1. 数列の最後の数値を無視している

x 2 x 3 x 4 => [[2,1],[3,1],[0,0]]

投稿2019/05/06 06:40

編集2019/05/06 06:43
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/05/06 06:56

回答ありがとうございます! 降順にソートしてからじゃないと、おっしゃるように数えれないですね・・・。 本当にありがとうございます。 それをやってから、ある数字の個数を数える という流れがよさそうですので 書き直します。 本当に助かりました。
退会済みユーザー

退会済みユーザー

2019/05/06 07:38

ちゃんと動きました。 本当にありがとうございます!
asm

2019/05/06 07:40

アイデアとしては、数値の種類が10^5までしかない int[100000]でも400kb 頻度情報だけとってから変換していくのもありですね
guest

0

[] だらけで見難かったのでマップ自作でしてみました. 性能は二の次です.

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5/**** value sorted map ****/ 6typedef struct { 7 int key; 8 int value; 9} MAP_ENTRY; 10 11typedef struct { 12 int size; 13 MAP_ENTRY *entries; 14} MAP; 15 16void init_map(MAP *map) { 17 map->size = 0; 18 map->entries = NULL; 19} 20 21int get_value(MAP *map, int key) { 22 MAP_ENTRY *entry = map->entries; 23 for(int i=0; i<map->size; i++, entry++) if(entry->key == key) return entry->value; 24 return -1; //無し 25} 26 27void set_value(MAP *map, int key, int value) { 28 MAP_ENTRY *entry = map->entries; 29 for(int i=0; i<map->size; i++, entry++) { 30 if(entry->key == key) { 31 for(; entry>map->entries; entry--) { 32 if((entry-1)->value >= value) break; //valueの大きい順 33 memcpy(entry, entry-1, sizeof(MAP_ENTRY)); 34 } 35 entry->key = key; 36 entry->value = value; 37 break; 38 } 39 } 40} 41 42void add_entry(MAP *map, int key, int value) { 43 MAP_ENTRY *new_entries = (MAP_ENTRY *)malloc(sizeof(MAP_ENTRY)*(map->size+1)); 44 MAP_ENTRY *old_entries = map->entries; 45 map->entries = new_entries; 46 47 int flag = 0; 48 if(old_entries != NULL) { 49 for(int i=0; i<map->size; i++) { 50 if(flag == 0 && old_entries[i].value < value) { //valueの大きい順 51 new_entries->key = key; 52 new_entries->value = value; 53 new_entries++; 54 flag = 1; //今後 if 文に入らないよう 55 } 56 memcpy(new_entries++, &old_entries[i], sizeof(MAP_ENTRY)); 57 } 58 free(old_entries); 59 } 60 if(flag == 0) { 61 new_entries->key = key; 62 new_entries->value = value; 63 } 64 65 map->size ++; 66} 67 68int get_size(MAP *map) { 69 return map->size; 70} 71 72MAP_ENTRY *get_entry(MAP *map, int index) { 73 return &map->entries[index]; 74} 75 76/**** main ****/ 77int main(void) { 78 MAP first, second; 79 80 init_map(&first); 81 init_map(&second); 82 83 //入力 84 int n; 85 scanf("%d", &n); 86 for(int i=0, key=0; i<n; i++) { 87 MAP *map = (i%2 ? &second : &first); 88 scanf("%d", &key); 89 int value = get_value(map, key); 90 if(value == -1) { 91 add_entry(map, key, 1); 92 } else { 93 set_value(map, key, value+1); 94 } 95 } 96 97//並び替えれてるかのチェックに使う 98printf("first size=%d----------\n", first.size); 99for(int i=0; i<first.size; i++) printf("%d %d\n", first.entries[i].key, first.entries[i].value); 100printf("second size=%d----------\n", second.size); 101for(int i=0; i<second.size; i++) printf("%d %d\n", second.entries[i].key, second.entries[i].value); 102 103 104 int first_size = get_size(&first); 105 int second_size = get_size(&second); 106 107 //使用数値決定 108 MAP_ENTRY *first_entry = get_entry(&first, 0); 109 MAP_ENTRY *second_entry = get_entry(&second, 0); 110 111 if(first_entry->key == second_entry->key) { 112 if(first_size <= 1 && second_size <= 1) { //全て同じ数値 113 printf("----------\n"); 114 printf("%d\n", second_entry->value); 115 exit(0); 116 } 117 if((first_size >= 2 && second_size >= 2 && first_entry->value < second_entry->value) || 118 (first_size >= 2 && second_size <= 1)) { 119 first_entry = get_entry(&first, 1); 120 } else { 121 second_entry = get_entry(&second, 1); 122 } 123 } 124 125 //カウント 126 int ans = 0; 127 for(int i=0; i<first_size; i++) { 128 MAP_ENTRY *entry = get_entry(&first, i); 129 if(entry->key != first_entry->key) ans+=entry->value; 130 } 131 for(int i=0; i<second_size; i++) { 132 MAP_ENTRY *entry = get_entry(&second, i); 133 if(entry->key != second_entry->key) ans+=entry->value; 134 } 135 printf("----------\n"); 136 printf("%d\n", ans); 137 138 return 0; 139}

投稿2019/05/06 08:41

jimbe

総合スコア12648

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問