20240121超能力编程比赛总结
好久没比赛了~
c++刷题 超能力编程
#include <iostream>
using namespace std;
int main() {
int a,b,c;
cin >> a >> b >> c;
cout << a-b << " " << a+c << endl;
return 0;
}
观察包括中心点的上层,点数由1 3 5 7…构成,假设上层有x层,即每层有2x-1个点,则总点数有
Sn=(1+(2x-1))x/2个点,即x^ 2个。那么下层点数总和为x^ 2-1个,全部的点数总和为2x^2-1个
令n’为点数总和,则有sqrt((n’+1)/2)层(n=2xx-1,用x表示n’)
因此代码如下:
#include <stdio.h>
#include <math.h>
int main()
{
int n,x,i,j;
char c;
scanf("%d %c", &n, &c);
x = sqrt((n + 1) / 2); //利用整型的特性将小数去除(x为上层层数)
for (i = 0; i < x; i++) //打印上层
{
for (j = 0; j < i; j++)
printf(" ");
for (j = 0; j < 2 * (x - i) - 1; j++) //由2x-1演变
printf("%c", c);
printf("\n");
}
for (i = 2; i <= x; i++) //打印下层(下层无中心点)
{
for (j = 0; j < x - i; j++)
printf(" ");
for (j = 0; j < 2 * i - 1; j++)
printf("%c", c);
printf("\n");
}
printf("%d", n - 2 * x * x + 1); //给的个数-(2x^2-1)=剩下个数
return 0;
}
其实这题就是路哟骨【洛谷每日一题】P1320 压缩技术 上的
大家应该知道,每一个char只读入一个字符,所以可以利用这一点来搞事情 AC。
具体思路是这样的:储存上一个字符,然后与当前的输入比较即可
有一种东西叫做 while(cin>>a) 他可以让你知道不输入的时候才跳出循环 所以用这个东西测试的话,要么开freopen,要么用我们luogu那高端大气上档次的:在线IDE(在应用里面)
而最最重要的,也是你为什么只有10分的原因,就是题目的一句话:
(第一个数是N ,其余各位表示交替表示0和1 的个数,压缩码保证 N X N=交替的各位数之和)
就是万恶的这一句,导致我一开始的0分。所以说,大家一定,一定,一定要将初始值赋为‘0’(注意,不是0)
其他咋话不多说,请看代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
int i = 0; // 循环必备的变量
int N = 0; // 一行字符串的长度
int sum = 0; // 0或1的总个数
char ch = '0'; // 用来存储每一次数组内每个元素所要比较的对象
char str1[40000] = {
0}; // 存放总的字符串
char str2[200] = {
0}; // 存放每一行字符串
scanf("%s", str2); // 输入第一行,以确定N
N = strlen(str2); // N等于第一行字符串的长度
strcat(str1, str2); // 该函数类似Linux的cat命令,把一个字符串接到另一个字符串的末尾
for (i = 2; i <= N; i++) // 输入第2~N行字符串
{
scanf("%s", str2);
strcat(str1, str2); // 将输入的每个字符串接到总字符串上
}
printf("%d ", N); // 打印出N的值
for (i = 0, sum = 0; i <= N * N; i++) // “<=”是为了打印出最后一个值
{
// 因为字符串以\0结尾,必与前面的值不同,从而把最后一个值打印
if (ch == str1[i]) // 相同就++
sum++;
else
{
ch = str1[i]; // 不相同就把那个不相同的值赋给它
printf("%d ", sum); // 打印出sum的值
sum = 1; // 将sum重新定义为1,因为这个不同的字符也算一个
}
}
return 0;
}
这题没做出来~
思路一
如果我们要求横向连成一条线,那么所有的方格可以这么编码:
0 0 0
1 1 1
2 2 2
这样子,我们可以看到数组下标和编码的规律:m[i][j] = i. 同理,纵向的规律就是m[i][j] = j. 但是斜向怎么办呢?首先,编码如下:
1 0 0 0 0 1
0 1 0 or 0 1 0
0 0 1 1 0 0
- 对于情况(一) ,有m[i][j] = i==j
- 对于情况(二) ,有m[i][j] = (i+j==2)
所以,我们可以存两个二维数组:int a[3][4],b[3][4];
这是什么意思呢?一共存两个数组表示:一共有两个玩家;第一个长度表示:刚才那4个公式得出的值,将其作为下标;第二个长度表示,一共有4个公式,所以一共有4种结果。二维数组中存什么值呢?
数组中可以存这一方,一共有多少个棋子下在了这个公式所对应的地方,只要数组中的一个值成为了3,就代表连成一线,输出,整段代码结束。
思路二
缩短思路:很多dalao用二维数组模拟3×3的方格,一维模拟:
用的是a[x][y],在我这里就变成了a[(x-1)×3+y]
例子:a[1][1]→a[1] a[2][3]→a[6] a[3][2]→a[8]
还有一个就是大家判定一条线时,很多人是如果全0,就是小a赢,全1就是uim赢,我觉得可以先判断是否都一样,都一样再判断其中任意一个是0还是1,这样也可以简洁一些。
注意:本人用的思路二
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,x,p=0,q=0,r=0,a[1111]; string s;
cin>>s; //读入
for (i=0;i<s.size();i++)
{
x=int(s[i])-48;
a[x]=i%2; //一维数组模拟
}
if (a[1]==a[5]&&a[5]==a[9]) {
if (a[1]==0) p=1; else q=1; r=1;} //如同↘样的对角线
if (a[3]==a[5]&&a[5]==a[7]) {
if (a[3]==0) p=1; else q=1; r=1;} //如图↙样的对角线(复制上面直接修改)
for (i=1;i<=3;i++) if (a[i]==a[i+3]&&a[i+3]==a[i+6]) {
if (a[i]==0) p=1; else q=1; r=1;} //每列判断是否一致
for (i=1;i<=9;i+=3) if (a[i]==a[i+1]&&a[i+1]==a[i+2]) {
if (a[i]==0) p=1; else q=1; r=1;} //每行判断是否一致
if (p&&!q) cout<<"a"; if (q) cout<<"b"; if (r) {
cout<<""; return 0;} //输出,""指不输出
cout<<"c";
}