此題讀入三整數後,利用以下 C 語言程式碼即可解:
j = (K + P) % N;By David.K
if (j == 0) j = N;
p11805題目連結
回ACM題庫目錄
回首頁
學習程式設計,語法固然重要,也是許多程式設計課程的教學重點。但是看的懂 C ,不見得會用 C 來解決問題(Problem solving),所以學會解題是重點中的重點。 學習C語言的不二法門,就是從寫程式解題開始,這裡的考古題由淺而深,循序漸進,對初學者甚有助益。 ACM 協會針對每年程式設計比賽的練習需求,建立一個線上的題庫與評分系統,希望藉由題庫練習的機會,在此心得分享,讓有心學習程式解題的人,能有個溝通成長的橋樑。
j = (K + P) % N;By David.K
if (j == 0) j = N;
#define LEN 1000
char seq1[LEN + 1], seq2[LEN + 1];
int lcs_length(int s1Len, int s2Len)
{
int i, j;
int table[s1Len + 1][s2Len + 1];
memset(table, 0, sizeof(table));
for(i = 1; i <= s1Len; ++i) {
for(j = 1; j <= s2Len; ++j) {
if(seq1[i - 1] == seq2[j - 1])
table[i][j] = table[i - 1][j - 1] + 1;
else if(table[i - 1][j] > table[i][j - 1])
table[i][j] = table[i - 1][j];
else
table[i][j] = table[i][j - 1];
}
}
return table[s1Len][s2Len];
}
int main()
{
while (gets(seq1))
{
gets(seq2);
int s1Len = strlen(seq1), s2Len = strlen(seq2);
printf("%d\n", lcs_length(s1Len, s2Len));
}
return 0;
}
struct Dice主程式內,讀入翻動次數 n 次後,先初始化骰子數字各在哪些方位:
{
int up, down, north, east, south, west;
};
struct Dice d;
d.up = 1, d.down = 6, d.north = 2,最後只要依照相對面的骰子總和為 7 以及空間概念,就可寫出來:
d.east = 4, d.south = 5, d.west = 3;
while (n --)
{
scanf("%s", str);
if (str[0] == 's') /* 南 */
d.south = d.up, d.up = d.north,
d.down = 7 - d.up, d.north = 7 - d.south;
if (str[0] == 'n') /* 北 */
d.down = d.north, d.north = d.up,
d.up = 7 - d.down, d.south = 7 - d.north;
if (str[0] == 'w')
d.down = d.west, d.west = d.up,
d.up = 7 - d.down, d.east = 7 - d.west;
if (str[0] == 'e')
d.east = d.up, d.up = d.west,
d.down = 7 - d.up, d.west = 7 - d.east;
}
printf("%d\n", d.up);
#define SIZE 8最後,在主程式如此呼叫:
#define LEN 7
int n, row, col, sI, sJ, eI, eJ;
char letters[LEN + 1] = {'@', 'I', 'E', 'H', 'O', 'V', 'A', '#'};
char path[LEN];
char stone[SIZE][SIZE + 1];
void visit(int i, int j, int index)
{
if (letters[index] != stone[i][j]) return;
if (i == eI && j == eJ)
{
int k;
if (path[0] == 'r') printf("right");
else if (path[0] == 'l') printf("left");
else if (path[0] == 'f') printf("forth");
for (k = 1; k < LEN; k ++)
{
if (path[k] == 'r') printf(" right");
else if (path[k] == 'l') printf(" left");
else if (path[k] == 'f') printf(" forth");
}
printf("\n");
}
/* 左 */
if (j - 1 >= 0) path[index] = 'l', visit(i, j - 1, index + 1);
/* 右 */
if (j + 1 < col) path[index] = 'r', visit(i, j + 1, index + 1);
/* 前 */
if (i - 1 >= 0) path[index] = 'f', visit(i - 1, j, index + 1);
}
scanf("%d %d", &row, &col);
for (i = 0; i < row; i ++)
{
scanf("%s", stone[i]);
if (i == 0)
{
for (j = 0; j < col; j ++)
if (stone[i][j] == '#') eI = i, eJ = j;
}
if (i == row - 1)
{
for (j = 0; j < col; j ++)
if (stone[i][j] == '@') sI = i, sJ = j;
}
}
visit(sI, sJ, 0);
first = 1;
if (ch[0] == '/')
{
tmp = 0;
for (i = 0; (c = m[i]); i ++)
{
tmp *= b;
tmp += c - '0';
j = tmp / n;
if (j != 0) first = 0;
if (!first) printf("%lld", j);
tmp %= n;
}
if (first) printf("0");
printf("\n");
}
if (ch[0] == '%')
{
for (i = 0, tmp = 0; (c = m[i]); i ++)
{
tmp *= b;
tmp += c - '0';
tmp %= n;
}
printf("%lld\n", tmp);
}
#define SIZE 800
#define LEN 2000
int p[SIZE + 1][LEN + 1] = {0};
char output[SIZE + 1][LEN + 1];
void create()
{
int i;
p[0][0] = 1;
p[1][0] = 0;
output[0][0] = '1';
output[0][1] = '\0';
output[1][0] = '0';
output[1][1] = '\0';
int j, k, s, count = 0;
for (i = 2; i <= SIZE; i ++)
{
for (j = 0; j <= LEN; j ++)
{
p[i][j] += (p[i - 1][j] + p[i - 2][j]) * (i - 1);
p[i][j + 1] += p[i][j] / 10, p[i][j] %= 10;
}
for (j = LEN; j >= 0; j --)
if (p[i][j] > 0) break;
for (k = j, s = 0; k >= 0; k --, s ++)
output[i][s] = p[i][k] + '0';
output[i][s] = '\0';
}
}
int main()
{
int n;
create();
while (scanf("%d", &n) == 1 && n != -1)
puts(output[n]);
return 0;
}
牛數量 | 車數量 | 開門數 | 門總數 |
2 | 1 | 1 | 3 |
牛數量 | 車數量 | 開門數 | 門總數 |
5 | 3 | 2 | 8 |
牛數量 | 車數量 | 開門數 | 門總數 |
NCOWS | NCARS | NSHOW | DOORS (= NCOWS + NCARS) |
#define SIZE 1000最後只需將被除數從大到小一個一個讀入,每次讀入都要乘上進位制,再去和 r 取餘數,最後要轉回進位制印出。
char p[SIZE + 1], m[10], print[SIZE + 1];
int b, r;
int get10Basic()
{
int n = 0, i;
int len = strlen(m);
for (i = 0; i < len; i ++)
n = n * b + (m[i] - '0');
return n;
}
主程式內 ....
scanf("%s %s", p, m);
int len = strlen(p);
int i;
r = get10Basic();
int n = 0;printbBasic 函式程式碼:
for (i = 0; i < len; i ++)
{
n *= b;
n += p[i] - '0';
n %= r;
}
printbBasic(n);
void printbBasic(int n)
{
int i = 0, j;
for ( ; n; n /= b)
print[i ++] = n % b;
if (i == 0) printf("0");
for (j = i - 1; j >= 0; j --)
printf("%c", print[j] + '0');
printf("\n");
}
int n, m;
int getInt()
{
char ch;
int n = 0;
while( ch = getchar())
if(ch != ' ' && ch != '\n') break;
n = ch - 48;
while( ch = getchar())
{
if(ch == ' ' || ch == '\n') break;
n = n * 10 + ch - 48;
}
return n;
}
主程式內 ....
while ((n = getInt()) && (m = getInt()))
{
int student[n + 1];
religionID = 1, count = 0;
memset(student, 0, sizeof(student));
while (m --)
{
i = getInt(), j = getInt();
if (student[i] == 0 && student[j] == 0)
{
student[i] = religionID, student[j] = religionID;
religionID ++;
count ++;
}
else if((student[i] != 0 && student[j] == 0) ||
(student[i] == 0 && student[j] != 0))
{
tmp = student[i] < student[j] ? student[j] : student[i];
student[i] = tmp, student[j] = tmp;
}
else if (student[i] != student[j])
{
tmp = student[j];
replace = student[i];
for (s = 1; s <= n; s ++)
if (student[s] == tmp) student[s] = replace;
count --;
}
}
/* for (i = 1; i <= n; i ++)
printf("%d ", student[i]);
printf("\n"); */
for (i = 1; i <= n; i ++)
if (student[i] == 0) count ++;
printf("Case %d: %d\n", caseNum ++, count);
}
scanf("%d %d", &n, &m);接下來用以上敘述的概念寫成分群並且計算數量的方法,順便記錄最大值,寫成 C 語言程式碼如下:
int friends[n + 1], record[n + 1], max = 0;
count = 0, groupID = 1;
memset(friends, 0, sizeof(friends));
memset(record, 0, sizeof(record));
while (m --)
{
scanf("%d %d", &a, &b);
if (friends[a] == 0 && friends[b] == 0)
{
friends[a] = groupID, friends[b] = groupID;
record[groupID] = 2;
if (max < record[groupID]) max = record[groupID];
groupID ++;
count ++;
}
else if((friends[a] != 0 && friends[b] == 0) ||
(friends[a] == 0 && friends[b] != 0))
{
tmp = friends[a] < friends[b] ? friends[b] : friends[a];
friends[a] = tmp, friends[b] = tmp;
record[tmp] ++;
if (max < record[tmp]) max = record[tmp];
}
else if (friends[a] != friends[b])
{
tmp = friends[b];
replace = friends[a];
record[tmp] = 0;
for (s = 1; s <= n; s ++)
if (friends[s] == tmp) friends[s] = replace, record[replace] ++;
if (max < record[replace]) max = record[replace];
count --;
}
/* for (s = 1; s <= n; s ++)
printf("%d ", record[s]);
printf("\n"); */
}
printf("%d\n", max);
#define SIZE 101最後寫一函式,利用回溯演算法將每一種可能的方法全部試過,如果超過我們所定義數值,只有剛好等於我們定義數值,才會被列出。
int print[SIZE];
int GCD[SIZE][SIZE];
int S, t;
int gcd(int a,int b)
{
if (a % b == 0){ return b;}
return gcd(b, a % b);
}
主程式內 ....
int a, b, n;
for(a = 1; a < SIZE; a ++)
for(b = 1; b < SIZE; b ++)
GCD[a][b] = gcd(a,b);
void find (int index, int n, int sum)最後在主程是如此呼叫:
{
int i, j;
if (index == t && sum == S)
{
printf("%d", print[0]);
for (i = 1; i < index; i ++)
printf(" %d", print[i]);
printf("\n");
return;
}
if (sum >= S) return;
for (; n <= S - sum; n ++)
{
for (j = 0; j < index; j ++)
if (GCD[print[j]][n] != 1) break;
if (j == index && S - sum >= n)
{
print[index] = n;
find(index + 1, n, sum + n);
}
}
}
scanf("%d", &n);
for (i = 1; i <= n; i ++)
{
scanf("%d %d", &S ,&t);
printf("Case %d:\n", i);
find(0, 1, 0);
}
* If N ≤ 100, then f91(N) = f91(f91(N+11));
* If N ≥ 101, then f91(N) = N-10.
#define SIZE 10001
int money[SIZE], record[SIZE];
int getInt()
{
char ch;
int n = 0, isNegative = 0;
while(ch = getchar())
if(ch != ' ' && ch != '\n') break;
if (ch == '-') isNegative = 1;
else n = ch - 48;
while( ch = getchar())
{
if(ch == ' ' || ch == '\n') break;
n = n * 10 + ch - 48;
}
if(isNegative) return -n;
return n;
}
主程式內 ....
while (n = getInt())
{
for (i = 0; i < n; i ++)
money[i] = 0, record[i] = 0;
int max = 0;
money[0] = getInt();
if (money[0] <= 0)
record[0] = 0;
else
record[0] = money[0], max = money[0];
for (i = 1; i < n; i ++)
{
money[i] = getInt();
record[i] = money[i] < money[i] + record[i - 1] ?
money[i] + record[i - 1] : money[i];
if (record[i] > max) max = record[i];
}
if (max == 0) puts("Losing streak.");
else printf ("The maximum winning streak is %d.\n", max);
}
#define SIZE 21
int luggage[SIZE], changeLine, index;
int getInt()
{
char ch;
int n = 0;
changeLine = 0;
while( ch = getchar())
if(ch != ' ' && ch != '\n') break;
n = ch - 48;
while( ch = getchar())
{
if(ch == ' ' || ch == '\n') break;
n = n * 10 + ch - 48;
}
if (ch == '\n') changeLine = 1;
return n;
}
主程式內 ....
index = 0, changeLine = 0, a = 0, b = 0;
while (!changeLine)
{
luggage[index] = getInt();
for (i = index; i >= 1; i --)
if (luggage[i] > luggage[i - 1])
tmp = luggage[i], luggage[i] = luggage[i - 1], luggage[i - 1] = tmp;
else break;
index ++;
}
for (i = 0; i < index; i ++)
{
if (a == b) a += luggage[i];
else if (a > b) b += luggage[i];
else a += luggage[i];
}
if (a == b) puts("YES");
else puts("NO");
#define SIZE 101
int classID[SIZE];
int index, n, m, c, r;
int getInt()
{
char ch;
int n = 0;
while( ch = getchar())
if(ch != ' ' && ch != '\n') break;
n = ch - 48;
while( ch = getchar())
{
if(ch == ' ' || ch == '\n') break;
n = n * 10 + ch - 48;
}
return n;
}
int isFind(int low, int high, int n)
{
int mid;
if (low > high) return -1;
else
{
mid = (low + high) / 2;
if (n == classID[mid])
return mid;
else if (n < classID[mid])
return isFind(low, mid - 1, n);
else
return isFind(mid + 1, high, n);
}
}
主程式內 ....
while ((n = getInt()))
{
index = 0;
m = getInt();
while (n --)
{
id = getInt();
classID[index] = id;
for (i = index; i >= 1; i --)
if (classID[i] < classID[i - 1])
tmp = classID[i], classID[i] = classID[i - 1], classID[i - 1] = tmp;
else break;
index ++;
}
int error = 0, f;
while (m --)
{
c = getInt(), r = getInt();
int count = 0, find;
while (c --)
{
f = getInt();
find = isFind(0, index, f);
if (find != -1) count ++;
}
if (count < r) error = 1;
}
if (error) puts("no");
else puts("yes");
}
#define SIZE 101
struct player
{
int win;
int lose;
};
struct player p[SIZE];
scanf("%d", &k);
for (i = 1; i <= n; i ++)
p[i].win = 0, p[i].lose = 0;
game = k * n * (n - 1) / 2;
while (game --)
{
scanf("%d %s %d %s", &p1, f1, &p2, f2);
int kind1, kind2;
if (f1[0] == 'r') kind1 = 1;
else if (f1[0] == 'p') kind1 = 2;
else kind1 = 3;
if (f2[0] == 'r') kind2 = 1;
else if (f2[0] == 'p') kind2 = 2;
else kind2 = 3;
if (kind1 > kind2)
{
j = kind1 - kind2;
if (j == 1) p[p1].win ++, p[p2].lose ++;
else p[p2].win ++, p[p1].lose ++;
}
else if (kind1 < kind2)
{
j = kind2 - kind1;
if (j == 1) p[p2].win ++, p[p1].lose ++;
else p[p1].win ++, p[p2].lose ++;
}
}
int total, win;
for (i = 1; i <= n; i ++)
{
win = p[i].win;
total = win + p[i].lose;
if (total == 0) printf("-\n");
else printf("%.3f\n",(float)win / (float)total);
}
scanf("%d", &n);
while (n --)
{
error = 0;
scanf("%d", &m);
scanf("%d %d", &y1, &y2);
sub = y1 - y2;
m --;
while (m --)
{
scanf("%d %d", &y1, &y2);
if (sub != y1 - y2) error = 1;
}
if (error) printf("no\n");
else printf("yes\n");
if (n) printf("\n");
}
for (i = 0; i < 36; i ++)接著我寫一函式,傳入兩整數,一為轉換為錢之整數,一為此整數的進位制。函式程式碼如下:
scanf("%d", &money[i]);
int getMoney(int n, int base)最後將 2 - 36 進位與欲印出的數字丟到上述函式轉換錢,並且進行比較,比較後記錄最小值,最後印出即可。C 語言程式碼如下:
{
int nMoney = 0;
for (; n; n /= base)
nMoney += money[n % base];
return nMoney;
}
index = 0;
scanf("%d", &m);
for (i = 0; i < m; i ++)
{
scanf("%d", &k);
index = 0;
min = getMoney(k, 2);
best[index ++] = 2;
for (j = 3; j <= 36; j ++)
{
count = getMoney(k, j);
if (min == count) best[index ++] = j;
if (min > count) min = count, index = 0, best[index ++] = j;
}
printf("Cheapest base(s) for number %d:", k);
for (j = 0; j < index; j ++)
printf(" %d", best[j]);
printf("\n");
}
#define SIZE 23
struct Crew
{
char name[12];
};
struct Crew c[SIZE];
int W[SIZE][SIZE];
主程式內 ....
for (k = 1; k <= n; k ++)
for (i = 1; i <= n; i ++)
for (j = 1; j <= n; j ++)
{
if (i != j && W[i][k] != 0 && W[k][j] != 0)
{
int m = W[i][k] + W[k][j];
if (W[i][j] == 0) W[i][j] = m;
else if (m < W[i][j]) W[i][j] = m;
}
}
for (i = 1, min = 0; i <= 1; i ++)
for (j = 1; j <= n; j ++)
if (i != j)
min += W[i][j];
minID = 1;
int count;
for (i = 2; i <= n; i ++)
{
for (j = 1, count = 0; j <= n; j ++)
{
if (i != j)
count += W[i][j];
}
if (min > count)
min = count, minID = i;
}
printf("Case #%d : %s\n", caseNum ++, c[minID].name);