没错,CSP-S 我勉强晋级,继续参加了今年的NOIP(就当是给我的高二决战练手了)。总体来说,我感觉NOIP题目比CSP的简单很多(当然对于那些dalao们来说都一样,都能AK)。
首先,来复盘一下这四个半点:
拿到题目,先看了一眼T1,好像很水的样子(QAQ),感觉能AC,花了差不多一个点到一个半点写了个埃氏筛,大样例自己测了一下,1s内应该能跑完,就放在一边不管了。(也有可能我数数不准。。)
考场代码:
#include<bits/stdc++.h>
using namespace std;
int a[10000010];
void work1(){
for(register int i(1) ; i<=200050 ; i=-~i){
if(i%7 == 0) a[i] = 1;
else{
int n = i;
while(n>0){
if(n%10 == 7){
for(register int j=i ; j<=200050 ; j+=i){
a[j] = 1;
}
}
n/=10;
}
}
}
}
void work2(){
for(register int i(1) ; i<=1e7 ; i=-~i){
if(i%7 == 0) a[i] = 1;
else{
int n = i;
while(n>0){
if(n%10 == 7){
for(register int j=i ; j<=1e7 ; j+=i){
a[j] = 1;
}
}
n/=10;
}
}
}
}
int main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
int t;
scanf("%d",&t);
if(t <= 10000)work1();
else work2();
while(t--){
int m;
scanf("%d",&m);
if(a[m] == 1){
printf("-1\n");
continue;
}
else{
for(register int i(m+1) ; ; i=-~i){
if(a[i] == 0){
printf("%d\n",i);
break;
}
}
}
}
return 0;
}
T1应该就这样了。
T2的话,拿到题先看了差不多15分钟,觉得好像能做,又好像不会做(还是太菜了)。于是便在那推部分分k=1,发现推了半个点没退出来,果断放弃,最后撇了个随机数。
#include<bits/stdc++.h>
using namespace std;
const int mod = 998244353;
const int M = 1010;
int v[M];
int n,m,k;
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(register int i(1) ; i<=m+1 ; i=-~i){
scanf("%d",&v[i]);
}
srand(time(0));
printf("%d\n",rand()%1049);
return 0;
}
现在大概还剩下两个半点左右
先看的T4,发现光是题目描述就读的有些费劲,看样例和测试点,果断放弃,直接看天骗分。
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("chess.in","r",stdin);
freopen("chess.out","w",stdout);
int t;
scanf("%d",&t);
while(t--){
int n,m,q;
scanf("%d%d%d",&n,&m,&q);
for(register int i(1) ; i<=q ; i=-~i){
cout << 1 << endl;
}
}
return 0;
}
最后剩大概一个小时四十分钟,都在做T3
题目描述好像很简单的样子,不过就是一个方差嘛(不是)。然后就随手打了两个修改的函数,从前往后修改n次。
正当我自以为过了的时候(看来我把这题想的太简单了),第一个样例过了,从第二个开始我输出的数比答案大很多。/(ㄒoㄒ)/~~
于是我发现我这个肯定不是最优的,接着想贪心,先是把这个数组中的每一个数两边的差值从小到大排序,按顺序修改,发现也是不对;接着从大到小排,同上。
于是心态有点崩,还剩1个点左右,考场上就想着怎么骗分,于是我从头到尾,从尾到头,从中间向两边······整了好几个循环上去,发现虽然我输出的数变小了,但还是不对。
就这么坐了20分钟,突然想到了爆搜吧,应该能过前20%的数据。打了个dfs,好在第一个和第二个样例过了,然后就跑不出来后面的样例了(毕竟复杂度太高)
考场代码如下
#include<bits/stdc++.h>
using namespace std;
int n;
const int M = 10010;
int a[M];
bool vis[M];
double ans=1e9;
bool check(int x){
if((a[x-1] + a[x+1] - a[x]) >= a[x-1] && (a[x-1] + a[x+1] - a[x]) <= a[x+1]) return 1;
return 0;
}
int modify(int x){
return a[x] = a[x-1] + a[x+1] - a[x];
}
double sum(){
double pingjun = 0;
double fangcha = 0;
for(register int i(1) ; i<=n ; i=-~i) pingjun += (double)a[i];
pingjun /= (double)n;
for(register int i(1) ; i<=n ; i=-~i) fangcha += (double)(a[i]-pingjun)*(a[i]-pingjun);
fangcha /= (double)n;
return fangcha;
}
/*struct chazhi{
int id;
int cha;
}b[M];
bool cmp(chazhi a,chazhi b){
return a.cha < b.cha;
}*/
void dfs(){
for(register int i(2) ; i<=n-1 ; i=-~i){
if(check(i) == 1 && !vis[i]){
if(i == n-1) ans = min(ans,sum());
vis[i] = 1;
dfs();
//if(i == n-1) ans = min(ans,sum());
vis[i] = 0;
modify(i);
vis[i] = 1;
dfs();
vis[i] = 0;
}
}
return;
}
int main(){
freopen("variance.in","r",stdin);
freopen("variance.out","w",stdout);
scanf("%d",&n);
for(register int i(1) ; i<=n ; i=-~i) scanf("%d",&a[i]);
/*for(register int j(1) ; j<=n ; j=-~j){
for(register int i(2) ; i<=n-1 ; i=-~i){
int fangcha = sum();
if(check(i) == 1){
modify(i);
ans = min(ans,sum());
}
}
}
for(register int j(1) ; j<=n ; j=-~j){
for(register int i(1) ; i<=n-2 ; i=-~i){
int fangcha = sum();
if((a[b[i].id+2] + a[b[i].id] - a[b[i].id+1] >= a[b[i].id+1] && a[b[i].id+1] < fangcha) || (a[b[i].id+2] + a[b[i].id] - a[b[i].id+1] <= a[b[i].id+1] && a[b[i].id+1] > fangcha)){
modify(b[i].id+1);
ans = min(ans,sum());
}
}
}*/
dfs();
printf("%lld\n",(long long)(ans * n * n));
return 0;
}
(从我的一堆注释中就能看出当时光想着骗分了)
但我怎么也没想到我的dfs好像打挂了/(ㄒoㄒ)/~~/(ㄒoㄒ)/~~
20分应该拿不到了(希望CCF造的数据能水点吧。。可怜可怜孩子吧)
总结一下:
自己学的知识不够,这次也只能打暴力了,接下来的时间一直到高二的决战,要多刷题积累经验,也要重视细节,重视一次AC率。
明年再战!