【刷题小结】2009-2011年苏州大学上机复试题
2009年上机复试题
题目
(1)用IE浏览器从FTP上下载org.dat,并保存在D盘的根目录下。
(2)此文件中按文本方式存放了一段其他文章,其中有若干长度小于15的十 进制或八进制数字,数字之间用“,”分开,数字内部存在且仅存在空格。
(3)八进制数以起始位“0”作为标示与十进制数区分。
(4)顺序读取这些数字将他们转变为十进制数后按从大到小的顺序排序后,输 出到D盘根目录下new.txt,每个数字一行。 eg:_235_,34_2,_043_1_,1_3 分别是:十进制235,十进制342.,八进制431,十进制13。_代表空格。
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int charToDec(char word[], int m);
int cmp(const void *a, const void *b);
void main()
{
FILE * fp1 = fopen("org.dat", "r");
FILE * fp2 = fopen("D:/new.txt", "w");
if (fp1 == NULL || fp2 == NULL) {
printf("FILE OPEN ERROR!\n");
exit(1);
}
int num[1000];
char word[20];
char letter;
int count = 0, len = 0, val;
bool flag = false, first=true;
memset(word, '\0', 20 * sizeof(char));
while ((letter = fgetc(fp1)) != EOF) {
if (letter == ',') {
if (flag) {
val = charToDec(word, 8);
}
else {
val = charToDec(word, 10);
}
memset(word, '\0', 20 * sizeof(char));
len = 0;
num[count] = val;
count++;
first = true;
flag = false;
val = 0;
}
else {
if (letter >= '0' && letter <= '9') {
if (first) {
if (letter == '0') {
flag = true;
}
else {
word[len] = letter;
len++;
first = false;
}
}
else {
word[len] = letter;
len++;
}
}
}
}
if (flag) {
val = charToDec(word, 8);
}
else {
val = charToDec(word, 10);
}
num[count] = val;
count++;
qsort(num,count,sizeof(int),cmp);
for (int i = 0; i < count; i++) {
fprintf(fp2, "%d\n", num[i]);
}
}
int charToDec(char word[], int m)
{
int n = 0;
for (int i = 0; word[i] != '\0'; i++) {
n = n * m + word[i] - '0';
}
return n;
}
int cmp(const void *a, const void *b)
{
return *(int *)a < *(int *)b ? 1 : -1;
}
2010年上机复试题
题目
(1)FTP上下载make.exe和org.dat,运行make.exe输入准考证后三位生成data.txt,文件为二进制编码
(2)data.txt内存有2048个整数,其中前n个为非0数,后2048-n个数为0,将其读入数组,计算非零数的个数n
(3)选出n个数中的最大数&最小数
(4)选出n个数中最大素数
(5)将n个数从大到小排序,并平均分成3段(若n非3的整数倍,则不考虑最后的1~2个数),选出中间段的最大数和最小数
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ARRAYSIZE 2048
void fileRead(FILE * fp, int num[], int * n);
int cmp(const void * a, const void * b);
bool isPreimer(int n);
void main()
{
FILE * fp = fopen("data.txt", "rb");
if (fp == NULL) {
printf("FILE OPEN ERROR!\n");
exit(1);
}
int num[ARRAYSIZE], maxnum, minnum, maxpreimer, n;
n = 0;
memset(num,0,sizeof(num));
fileRead(fp, num, &n);
//for (int i = 1; i < 1025; i++) {
// fwrite(&i, sizeof(int), 1, fp);
//}
//int j = 0;
/*for (int i = 0; i < 1024; i++)
{
fwrite(&i, sizeof(int), 1, fp);
}*/
qsort(num, n, sizeof(int), cmp);
maxnum = num[0];
minnum = num[n - 1];
for (int i = 0; i < n; i++) {
if (isPreimer(num[i])) {
maxpreimer = num[i];
break;
}
}
printf("非零数字个数为:%d\n", n);
printf("其中最大数为:%d\n", maxnum);
printf("其中最小数为:%d\n", minnum);
printf("其中最大素数为:%d\n", maxpreimer);
n = n - n % 3;
maxnum = num[n / 3];
minnum = num[n / 3 * 2 - 1];
printf("中间段最大数为:%d\n", maxnum);
printf("中间段最小数为:%d\n", minnum);
}
void fileRead(FILE * fp, int num[], int * n)
{
int temp;
while (fread(&temp, sizeof(int), 1, fp) && *n < ARRAYSIZE) {
if (temp != 0) {
num[*n] = temp;
*n = *n + 1;
}
}
}
int cmp(const void * a, const void * b)
{
return (*(int *)b - *(int *)a);
}
bool isPreimer(int n)
{
if (n <= 1) {
return false;
}
if (n == 2) {
return true;
}
for (int i = 2; i < (sqrt(n*1.0) + 1); i++) {
if (0 == n%i) {
return false;
}
}
return true;
}
2011年上机复试题
题目
第一道:输出1000~9999中满足一下条件的所有数:
(1)该数是素数
(2)十位数和个位数组成的数是素数,百位数和个位数组成的数是素数
(3)千位数和百位数组成的数是素数,千位数和十位数组成的数是素数
第二道:
从ftp上下载一个文本info.txt,其中是一段关于计算机历史的英文文档(不过是加过密的,打开看全是乱码),
要求密钥cip1和cip2以及解密后的第一个句子。条件:
(1)cip1和cip2都是八位无符号整数;
(2)加密过程:每次从文本中读出八位字符,然后将该字符和密钥交替异或便是该位置的密文。
如第1个字节与cip1异或,第2个字节和cip2异或,第3个字节和cip1异或,。。。,如此循环至结束。
最后输出cip1和cip2以及第一段完整的英文句子。
分析
第一题不难,只要区分好怎么求一个数的个十百千位就好。第二题我一开始抓到有点懵,似乎有点是n-1个条件求解n个数,这个明显不能求得唯一解啊。但是好在题目给了另外一个条件就是八位无符号整数,那就全都试一遍就好了。在有无符号方面我出了一些bug,毕竟不太熟悉。
代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
bool isPreimer(int n);
void findCode(char letters[], int n, char *cip1, char * cip2);
bool isLegalWord(char c);
void main()
{
// 第一题
for (int i = 1000; i < 10000; i++) {
if (isPreimer(i) && isPreimer(i % 100 / 10 + i % 10) && isPreimer(i % 1000 / 100 + i % 10) &&
isPreimer(i / 1000 + i % 1000 / 100) && isPreimer(i / 1000 + i % 100 / 10)) {
printf("%d\n", i);
}
}
// 第二题
// 生成数据文件
/*FILE * fp1 = fopen("data.txt","w");
FILE * fp2 = fopen("result.txt", "r");
if (fp1 == NULL || fp2==NULL) {
printf("FILE OPEN ERROR!\n");
exit(1);
}
char cip1 = 22, cip2 = 10;
char t;
int count = 1;
while (fscanf(fp2, "%c", &t) != EOF) {
if (count % 2 == 1) {
t = t^cip1;
}
else {
t = t^cip2;
}
fprintf(fp1,"%c",t);
count++;
}*/
FILE * fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("FILE OPEN ERROR!\n");
exit(1);
}
char letters[10000];
char t;
int count = 0;
memset(letters, '\0', sizeof(letters));
while (fscanf(fp, "%c", &t) != EOF) {
letters[count++] = t;
}
char cip1, cip2;
findCode(letters, count, &cip1, &cip2);
for (int i = 0; i < count; i++) {
if (i % 2 == 0) {
letters[i] = letters[i] ^ cip1;
}
else {
letters[i] = letters[i] ^ cip2;
}
}
printf("cip1:%d\ncip2:%d\n", cip1, cip2);
printf("%s\n", letters);
}
bool isPreimer(int n)
{
if (n <= 1) {
return false;
}
if (n == 2) {
return true;
}
for (int i = 2; i < (sqrt(n*1.0) + 1); i++) {
if (0 == n%i) {
return false;
}
}
return true;
}
void findCode(char letters[], int n, char *cip1, char * cip2)
{
char t;
int j;
bool flag1 = true, flag2 = true;
for (char i = 0; i >= 0 && i < 256; i++) {
for (j = 0; j < n && flag1; j = j + 2) {
t = i^letters[j];
if (!isLegalWord(t)) {
break;
}
}
if (j >= n) {
*cip1 = i;
flag1 = false;
}
for (j = 1; j < n && flag2; j = j + 2) {
t = i^letters[j];
if (!isLegalWord(t)) {
break;
}
}
if (j >= n) {
*cip2 = i;
flag2 = false;
}
}
}
bool isLegalWord(char c)
{
if ((c <= 'z'&&c >= 'a') || (c <= 'Z'&&c >= 'A') || c == ',' || c == '.' || c == '?' || c == ';' || c == ':'
|| c == '!' || c == '\\' || c == '\'' || c == '-' || c == '(' || c == ')' || c == ' ') {
return true;
}
return false;
}