【题解】2001-T1 数的计数
【题解】单词排序
NOIP/CSP-J复赛历年考点
2021CSP-J/S全国晋级二轮分数线公布
| 序号 | 省市 | CSP-J人数 | CSP-J晋级 | 晋级比例 | 最高分 | 晋级最低分 |
| 1 | 甘肃 | 134 | 133 | 99.25% | 86 | 15 |
| 2 | 宁夏 | 103 | 101 | 98.06% | 65 | 24 |
| 3 | 天津 | 463 | 451 | 97.41% | 86 | 15.5 |
| 4 | 云南 | 402 | 378 | 94.03% | 79.5 | 17 |
| 5 | 湖北 | 680 | 632 | 92.94% | 89.5 | 26 |
| 6 | 海南 | 186 | 170 | 91.40% | 73.5 | 29 |
| 7 | 陕西 | 493 | 447 | 90.67% | 93.5 | 28 |
| 8 | 广西 | 795 | 680 | 85.53% | 86 | 28 |
| 9 | 山西 | 773 | 628 | 81.24% | 95.5 | 30 |
| 10 | 贵州 | 447 | 331 | 74.05% | 71 | 30 |
| 11 | 吉林 | 454 | 332 | 73.13% | 91 | 33 |
| 12 | 河南 | 1114 | 798 | 71.63% | 88.5 | 34.5 |
| 13 | 内蒙古 | 56 | 40 | 71.43% | 58 | 34.5 |
| 14 | 黑龙江 | 354 | 205 | 57.91% | 82 | 24.5 |
| 15 | 新疆 | 425 | 238 | 56.00% | 81.5 | 39 |
| 16 | 江西 | 485 | 247 | 50.93% | 86.6 | 36.5 |
| 17 | 辽宁 | 475 | 23 | 50.32% | 90 | 40 |
| 18 | 湖南 | 1528 | 744 | 48.69% | 93.5 | 15 |
| 19 | 香港 | 72 | 35 | 48.61% | 100 | 45.5 |
| 20 | 河北 | 1122 | 518 | 46.17% | 93.5 | 40 |
| 21 | 澳门 | 103 | 39 | 37.86% | 82 | 31 |
| 22 | 重庆 | 1430 | 541 | 37.83% | 94 | 51.5 |
| 23 | 上海 | 2841 | 1007 | 35.45% | 94.5 | 52.5 |
| 24 | 安徽 | 4731 | 1558 | 32.93% | 98.5 | 34 |
| 25 | 北京 | 3397 | 941 | 27.70% | 96.5 | 53 |
| 26 | 四川 | 3028 | 704 | 23.25% | 98.5 | 17 |
| 27 | 江苏 | 4172 | 737 | 17.67% | 98.5 | 38 |
| 28 | 广东 | 5627 | 986 | 17.52% | 95.5 | 58.5 |
| 29 | 浙江 | 6067 | 946 | 15.59% | 98 | 66 |
| 30 | 山东 | 11450 | 1326 | 11.58% | 98 | 15 |
山东普及组分数线55
小学组43
如何估算时间复杂度
首先:
常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n^2)<Ο(n^3)<…<Ο(2^n)<Ο(n!)
时间复杂度可以简单理解为最多执行次数。
一、O(1)
一般情况下没有其他循环和递归调用,时间复杂度一般都是O(1)。比如下面这样的代码
#include<iostream> using namespace std; int main(){ int a=0,b=0,x=0,y=0; cin>>a>>b; x=a+b; y=a-b; if(x>y){ cout<<x; }else{ cout<<y; } return 0; }二、O(n)
一般情况下,一个循环的时间复杂度是O(n),多个循环并列也是取循环次数最多的那个作为时间复杂度。当数据量增大n倍,耗时增大n倍。
#include<iostream> using namespace std; int main(){ int a=n; cin>>n; for(int i=0;i<n;i++){ cout<<i; } return 0; }三、O(n2)、O(n*m)
双重循环嵌套一般就是O(n2)。当数据量增大n倍,耗时增大n方倍。
#include<iostream> using namespace std; int main(){ int n=0; cin>>n; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cout<<i; } } return 0; }如果循环嵌套外层循环是n,内层循环是m。
#include<iostream> using namespace std; int main(){ int n=0,m=0; cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<i; } } return 0; }这个时候的时间复杂度是O(n*m)。
四、O(logn)
当数据增大n倍时,耗时增大logn倍。
#include<iostream> using namespace std; int main(){ int n=0; cin>>n; for(int i=0;i<n;i++){ i*=2; cout<<i; } return 0; }本来循环次数是n,现在i*=2了。那么答案是log(2)(n)。
反着想也可以,原来循环n次,现在每次i变成原来的2倍,也就是2的k次方等于n。那么正好就是log(2)(n),即O(log n)
或者下面这样:
#include<iostream>using namespace std; int main(){ int n=0; cin>>n; while((n=n/2)>0){ cout<<n; } return 0; }时间复杂度也是O(logn)
五、O(nlogn)
一般归并排序和堆排序是O(nlogn)。
常见的是外层循环的时间复杂度是n,内层循环的时间复杂度是logn。
比如下面这样:
for(int i=1; i<=n; i++) { for(int j=1; j<=n; j+=i) { ..... //复杂度为O(1); } }注意:外层循环是n,内层循环j每次都增加i。
指针(三):指针与函数
指针(二):指针与数组
1.指针与数组的关系
指向数组的指针变量称为数组指针变量。“数组是内存上一块连续的空间”。数组名就是这块连续空间的首地址。
2.指针指向数组
一开始的数组定义与输出:
#include<iostream> #include<cstdio> using namespace std; int main(){ int a[10]; for(int i=0;i<5;i++){ cin>>a[i]; } for(int i=0;i<5;i++){ cout<<a[i]<<" "; } return 0; }指针操作也可以输入数据:
#include<iostream> #include<cstdio> using namespace std; int main(){ int a[10]; for(int i=0;i<5;i++){ scanf("%d",a+i); //本来写成scanf("%d",&a[i]); } for(int i=0;i<5;i++){ printf("%d ", *(a+i)); // } return 0; }上面这个操作,本来scanf("%d",&a)写法,其中&是取地址符,a是数组名,本来就表示数组空间的首地址,所以可以直接用。注意,这个地方不能用cin。
数组指向指针操作:
我们可以定义指针变量,让它来指向数组名。
#include<iostream> #include<cstdio> using namespace std; int main(){ int a[10]; int *p=a; for(int i=0;i<5;i++){ scanf("%d",p+i); //本来写成scanf("%d",&a[i]); } for(int i=0;i<5;i++){ printf("%d ", *(p+i)); } return 0; }2.指针的加减
指针也是变量,可以加减。
#include<iostream> #include<cstdio> using namespace std; int main(){ int a[10]={1,2,3,4,5}; int *pa=a; cout<<a[0]<<endl; //结果是1 cout<<pa<<endl; //0x70fdf0 cout<<*pa<<endl; //结果是1 pa++; cout<<pa<<endl; //0x70fdf4 cout<<*pa<<endl; //2 pa=pa+2; cout<<pa<<endl; //0x70fdfc cout<<*pa<<endl; //4 pa--; cout<<pa<<endl; //0x70fdf8 cout<<*pa<<endl; //3 return 0; }