3 条题解
-
0
#include<stdio.h> int main(){ int n,m; scanf("%d %d",&n,&m); int tot[101]; int i; for(i=0;i<n;i++){ scanf("%d",&tot[i]); } int j,k; for(i=0;i<m;i++){ for(j=n-1;j>=0;j--){ tot[j+1]=tot[j]; } tot[0]=tot[n]; } for(i=0;i<n;i++){ printf("%d",tot[i]); if(i!=n-1){ printf(" "); } } return 0; } -
0
题目要求输出数组,但并没有要求一定要对原数组进行操作,其实可以直接输出结果. 这需要用点数学知识.
数学知识讲解: 对于下标i,移动后变成(i + m),但(i + m)可能会超出数组范围,可以对它取余,得到下标i移动后应该到达的位置(i + m) % n. 不过,至少是我的输出方法,是从0到(n - 1)输出的,是直接输出移动后的数组,那就得根据移动后的下标反推移动前的下标,所以要对上述过程进行逆向操作。那么,理论上应该是(i' - m) % n (i' 表示移动后的下标),但由于C语言对于负数取余仍然得到的是负数,所以只好先得到反向移动值(m % n),然后(+ n)使所有反向移动值变正,得到移动前的下标(i' - (m % n) + n),再(% n),防止访问数组越界,最终得到((i' - (m % n) + n) % n).
代码如下,希望能给人带来启发:
#include <stdio.h> int main() { int n, m; int a[105] = {0}; scanf("%d %d", &n, &m); for (int i = 0; i < n; i ++) { scanf("%d", &a[i]); } m %= n; for (int i = 0; i < n; i ++) { int p = (i - m + n) % n; printf("%d ", a[p]); } return 0; } -
0
右移m个位置,可以等效为右移m次
注意索引的范围
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> int main(){ int i,j,n,m;scanf("%d %d",&n,&m); int a[n]; for(i=0;i<n;i++){ scanf("%d",&a[i]); } for(i=0;i<m;i++){ int b=a[n-1]; for(j=n-1;j>0;j--){ a[j]=a[j-1]; } a[0]=b; } for(i=0;i<n;i++){ printf("%d ",a[i]); } return 0; }
- 1
信息
- ID
- 24
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 302
- 已通过
- 143
- 上传者