当前位置: 代码迷 >> 综合 >> HAUT OJ 2021 新生周赛二 反思总结
  详细解决方案

HAUT OJ 2021 新生周赛二 反思总结

热度:61   发布时间:2023-12-04 03:20:22.0

问题 E: 牛牛的素数判断



问题描述:

牛牛最近学会了素数判断,但牛牛的朋友不相信想考考他,便问他:给你两个数a,b,判断a×b是否是素数。
素数是指大于1的正整数中,有且仅有两个因子的数。
(PS:1e11=10的11次方)

输入:

第一行输入一个整数T,代表T组数据。接下来T行(1<=T<=10),每行两个整数a,b(1<=a,b<=1e11)。

输出:

对于每一行的输入若,a×b是素数则输出一行YES,否则输出一行NO。

样例输入:

3
2 3
1 7
1 4

样例输出:

NO
YES
NO



原因分析:

数据太大自然不能相乘,还得用 long long, a*b为素数,素数又是只有1和本身相乘得到的,故只需判断两个数中是否有个1,并且另一个是否为素数.




解决方案:

#include<bits/stdc++.h>
using namespace std;
int prime (long long n)
{long long i,k=sqrt(n);if(n==1)return 0;if(n==2)return 1;for(i=2;i<=k;i++){if(n%i==0){return 0;}}return 1;
}
int main()
{long long a,b,t;cin>>t;while(t--){cin>>a>>b;if(a==1&&prime(b)||b==1&&prime(a)){cout<<"YES"<<endl;}elsecout<<"NO"<<endl;}}



问题 G: 牛牛的循环次数

问题描述:

牛牛知道,在编程中,需要考虑到时间复杂度,特别是对于循环的部分。例如,如果代码中出现

for(i=1;i<=n;i++) OP ;


那么做了n次OP运算,如果代码中出现

for(i=1;i<=n; i++)for(j=i+1;j<=n; j++) OP;


那么做了n*(n-1)/2 次OP 操作。
牛牛写了如下代码:

for(i=1;i<=n; i++)for(j=i+1;j<=n; j++)for(k=j+1;k<=n;k++)OP;


现在已知n,牛牛想知道做了多少次OP操作。

输入:

第一行输入1个整数T(1<=T<=100),代表有T组数据
接下来T行,每行一个正整数n(1<=n<=1000)

输出:

对于每一组数据,在一行中输出OP的操作次数。

样例输入:

4
3
4
5
6

样例输出:

1
4
10
20

原因分析:

三个for循环,其实就相当于在1~n中选三个数,即排列组合,但要注意一点:

拿 5举例,取1 2 3只有1 2  3没有2 3 1,即取的球只能从小到大排,即C(3,5)或者

A(3,n)/A(3,3) ,  C(3,5)可以理解为默认了三个数从小到大排.


解决方案:

1.杨辉三角求C

#include<bits/stdc++.h>
using namespace std;const int N = 2000;int c[N+1][N+1];void initc()
{c[0][0] = 1;for(int i=1; i<=N; i++) {c[i][0] = 1;for(int j=1; j<=N; j++)c[i][j] = (c[i-1][j-1] + c[i-1][j]);}
}int main()
{int t, n;initc();cin >> t;while(t--) {cin  >> n;cout << c[n][3] << endl;}return 0;
}

2.简化组合数运算.

有编号为1~5的5个小球,取3个小球,则有A(3,5)=60种情况,但每一组都出现了6次,如1,2,3这种组合有A(3,3)=6种情况,但只有(1,2,3)这种是满足要求的,因此可以得到公式A(3,n)/A(3,3)。

#include<stdio.h>
int main()
{int n,T;scanf("%d",&T);while(T--){scanf("%d",&n);int cnt=0;cnt=n*(n-1)*(n-2)/6;printf("%d\n",cnt);}}

 牛牛的数独

问题描述:

牛牛遇到了一个9×9的数独,你能帮牛牛判断数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
1.数字1-9在每一行只能出现一次。
2.数字1-9在每一列只能出现一次。
3.数字1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(如图)


原因分析:

思路很简单,有几个注意点.

1. 数组里 i,j对调即由行判断到列判断.

2.注意 ans[i][j]==0 时候直接continue;

3.判断九宫格的时候,可以先将9*9近似看成3*3,即两个for从0~3,然后每个大宫格里又有一个3*3的小宫格,即 再加俩循环, 

for(ii=3*i;ii<3*i+3;ii++)  
 for(jj=3*j;jj<3*j+j;jj++)


解决方案:

#include<bits/stdc++.h>
using namespace std;int main()
{int i,j,ans[10][10],ii,jj;for(i=0;i<9;i++){for(j=0;j<9;j++)cin>>ans[i][j];}for(i=0;i<9;i++){int a[10]={0};for(j=0;j<9;j++){if(ans[i][j]==0)continue;if(a[ans[i][j]]==0){a[ans[i][j]]=1;}else if(a[ans[i][j]]>0){printf("no\n");return 0;}}}for(i=0;i<9;i++){int a[10]={0};for(j=0;j<9;j++){if(ans[j][i]==0)continue;if(a[ans[j][i]]==0){a[ans[j][i]]=1;}else if(a[ans[j][i]]>0){printf("no\n");return 0;}}}for(i=0;i<3;i++){for(j=0;j<3;j++){int a[10]={0};for(ii=3*i;ii<3*i+3;ii++){for(jj=3*j;jj<3*j+j;jj++){if(ans[ii][jj]==0)continue;if(a[ans[ii][jj]]==0)a[ans[ii][jj]]=1;else if(a[ans[ii][jj]]>0){printf("no\n");return 0;}}}}}printf("yes\n");return 0;}

反思:

1.思维不够灵活,不断将问题复杂化.

2.太着急AC了,细节没注意到,第一题就wa,看清题.

3.继续加强对字符串的练习