2020春 USTC【程序设计II】课程作业
——第一章 A.RCR指令
Question:
在早期的Intel微处理器8086号CPU的机器代码中,除了有我们常学到的移位指令以外,还有特殊的循环移位指令,甚至更特殊的:RCR 循环右移指令。
-------------------- -----
——> | 1001101011010011 | ——> | 0 | ——> RCR operation
| -------------------- ----- |
| X C |
<————————————————————————————————————v
--------------------
| 1010011010110100 |
--------------------
Y: will equal to X after two RCRs.
简单来说,给定一个16比特的整数变量X,和一个特殊的1比特变量C,RCR指令将X的最低位移入C,C移入X的最高位,其余位正常右移——或者说,XC构成了17比特的变量,并在RCR指令下循环右移。
给定你两个16比特可表示的正整数X和Y,和一个1比特整数C,请问,能否对X和C做若干次RCR指令操作,使得X等于Y?
Input Description
第一行,1个整数T,表示数据组数。接下来是T组数据。
接下来的T行,每行有三个整数X、Y、C,其意义如上所述。
对于100% 的数据,1 ≤ T ≤ 2 000 000,0 ≤ X, Y≤ 65535,0 ≤ C ≤ 1。
Output Description
对于每组数据,输出一行,“YES” 或者 “NO”(大写,睁大你们的眼睛,大写),表示X能或不能与Y相等。
以下是代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
int main() {
int T = 0, x = 0, y = 0, temp = 0;
int a[500] = {0}, b[500] = {0}, temp_1[500] = {0};
short c[500] = {0}, c_0 = 0, z = 0;
short i = 0, j = 0, k = 0, flag = 0, flag_1 = 0, n = 0, m = 0;
scanf("%d", &T);
if(T < 500)
{
for (j = 0; j < T; j++)
{
scanf("%d%d%hd", &x, &y, &z);
if (x == y)
{
printf("YES\n");
flag = 1;
flag_1 = 1;
}
c_0 = z;
//if C == 1 at first
if (c_0 == 1)
{
temp = x + 65536;
for (i = 0; i <= 16; i++)
{
z = (x&1);
x = (temp >> 1);
if(z)
temp = (x | 65536);
else
temp = x;
if (x == y)
{
if (flag_1 == 0)
printf("YES\n");
flag = 1;
break;
}
}
}
if (c_0 == 0 )
{
temp = x;
for (i = 0; i <= 16; i++)
{
z = (x&1);
x = (temp >> 1);
if(z)
temp = (x | 65536);
else
temp = x;
if (x == y)
{
if (flag_1 == 0)
printf("YES\n");
flag = 1;
break;
}
}
}
if (flag == 0)
printf("NO\n");
flag = flag_1 = 0;
}
}
if(T >= 500)
{
n = T/500;
m = T%500;
for(k = 0; k < n; k++)
{
for (j = 0; j < 500; j++)
{
scanf("%d%d%hd", &a[j], &b[j], &c[j]);
if (a[j] == b[j])
{
printf("YES\n");
flag = 1;
flag_1 = 1;
}
c_0 = c[j];
//if C == 1 at first
if (c_0 == 1)
{
temp_1[j] = a[j] + 65536;
for (i = 0; i <= 16; i++)
{
c[j] = (a[j]&1);
a[j] = (temp_1[j] >> 1);
if(c[j])
temp_1[j] = (a[j] | 65536);
else
temp_1[j] = a[j];
if (a[j] == b[j])
{
if (flag_1 == 0)
printf("YES\n");
flag = 1;
break;
}
}
}
if (c_0 == 0 )
{
temp_1[j] = a[j];
for (i = 0; i <= 16; i++)
{
c[j] = (a[j]&1);
a[j] = (temp_1[j] >> 1);
if(c[j])
temp_1[j] = (a[j] | 65536);
else
temp_1[j] = a[j];
if (a[j] == b[j])
{
if (flag_1 == 0)
printf("YES\n");
flag = 1;
break;
}
}
}
if (flag == 0)
printf("NO\n");
flag = flag_1 = 0;
}
}
for (j = 0; j < m; j++)
{
scanf("%d%d%hd", &a[j], &b[j], &c[j]);
if (a[j] == b[j])
{
printf("YES\n");
flag = 1;
flag_1 = 1;
}
c_0 = c[j];
//if C == 1 at first
if (c_0 == 1)
{
temp_1[j] = a[j] + 65536;
for (i = 0; i <= 16; i++)
{
c[j] = (a[j]&1);
a[j] = (temp_1[j] >> 1);
if(c[j])
temp_1[j] = (a[j] | 65536);
else
temp_1[j] = a[j];
if (a[j] == b[j])
{
if (flag_1 == 0)
printf("YES\n");
flag = 1;
break;
}
}
}
if (c_0 == 0 )
{
temp_1[j] = a[j];
for (i = 0; i <= 16; i++)
{
c[j] = (a[j]&1);
a[j] = (temp_1[j] >> 1);
if(c[j])
temp_1[j] = (a[j] | 65536);
else
temp_1[j] = a[j];
if (a[j] == b[j])
{
if (flag_1 == 0)
printf("YES\n");
flag = 1;
break;
}
}
}
if (flag == 0)
printf("NO\n");
flag = flag_1 = 0;
}
}
return 0;
}
经验和教训
- 输入一组数据处理一组,代码运行时间过长,以空间换时间,定义大小适当的数组,将数据先集中录入到数组,再对数组中元素集中操作,可以缩短代码运行时间
- 使用
#define _CRT_SECURE_NO_WARNINGS
可以消除visual studio中对scanf
的警告 z = (x&1);
<=>z = (x % 2);
相当于判断x的奇偶,使用位运算速度快- 代码写的太丑,没有使用函数,全写在main函数里了,一定不能再犯😅