乱搞题 (不知道怎么分类)

  NOI元丹:https://www.luogu.org/problemnew/show/P1371

  题意概述:在给定的NOI序列中插入一个字符(任选),使得串中含有最多的NOI子序列。

  分类讨论。如果插入N,必然是插在最前面好,如果插入I,必然是插在最后面好。这个可以理解吧。

  比较麻烦的是插入O。(其实不考虑O这道题也能过,数据水的不可思议),分别讨论每个位置,看前面有几个N,后面有几个I,乘起来即为插入这个O的贡献。

  (原来考NOI的秘诀是炼丹啊

   
# include <cstdio>
# include <iostream>

using namespace std;

int n;
char c[100009];

long long addn()
{
    int N=1,NO=0;
    long long ans=0;
    for (int i=1;i<=n;i++)
    {
        if(c[i]=='N') N++;
        if(c[i]=='O') NO+=N;
        if(c[i]=='I') ans+=NO;
    }
    return ans;
}

long long addi()
{
    int N=0,NO=0;
    long long ans=0;
    for (int i=1;i<=n;i++)
    {
        if(c[i]=='N') N++;
        if(c[i]=='O') NO+=N;
        if(c[i]=='I') ans+=NO;
    }
    return ans+NO;
}

int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%c",&c[i]);
        while (c[i]!='N'&&c[i]!='O'&&c[i]!='I') scanf("%c",&c[i]);
    }
    long long ans=addn();
    ans=max(ans,addi());
    cout<<ans;
    return 0;
}
NOI元丹

   

  yyy loves Chemistry I:https://www.luogu.org/problemnew/show/P2394

  题意概述:输入n,输出n/23(保留8位小数);

  因为这个n的精度可能很高,于是就想到了边读入边算边输出。这时候我们发现输出的精度并不是很高....所以也没有必要全部读进来,读上15-6位就足够了,剩下的就不要啦。用long double,输入时是%Lf,注意L是大写。

  
# include <cstdio>
# include <iostream>

using namespace std;

long double a;

int main()
{
    scanf("%20Lf",&a);
    printf("%.8Lf",a/23.0);
    return 0;
}
2394

 

  好消息,坏消息:https://www.luogu.org/problemnew/show/P2629

  题意概述:给定一个数列,从一个断点往后加,期间不能出现负数,再从头加到断点处,期间还是不能有负数。问这样的断点个数。

  听说这是单调队列优化dp,一开始想到线段树,ST表。冷静分析一下...不就是...瞎搞吗...

  首先求一个前缀和,再对于前缀和数组求一个前缀min,一个后缀min,枚举断点,如果后缀min减去前缀和大于零,后缀和加上前缀min大于零,这个断点就是一个合法的答案,然后就...没啦。

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # define R register int
 4 
 5 using namespace std;
 6 
 7 const int maxn=1000050;
 8 int n,ans=0;
 9 int a[maxn],s[maxn],qm[maxn],hm[maxn];
10 
11 int main()
12 {
13     scanf("%d",&n);
14     for (R i=1;i<=n;++i)
15         scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
16     qm[1]=s[1];
17     for (R i=2;i<=n;++i)
18         qm[i]=min(qm[i-1],s[i]);
19     hm[n]=s[n];
20     for (R i=n-1;i>=1;--i)
21         hm[i]=min(hm[i+1],s[i]);
22     if(qm[n]>=0) ans++;
23     for (R i=2;i<=n;++i)
24     {
25         if(hm[i]-s[i-1]<0) continue;
26         if(s[n]-s[i-1]+qm[i-1]<0) continue;
27         ans++;
28     }
29     printf("%d",ans);
30     return 0;
31 }
好消息,坏消息

 

  [PA2014]Iloczyn:https://www.lydsy.com/JudgeOnline/problem.php?id=3713

  题意概述:给定一个不大于$1e9$的数字,问它是不是两个斐波那契数的乘积;

  这题一看就很数论,然而推了一下发现并不能找出什么结论来,后来写了一个暴力打表找规律,发现不大于$1e9$的斐波那契数非常少,只有$40$多个,所以暴力就行。注意一个小细节:$f[0]=0$,所以$0$是可以乘出来的。

  
 1 # include <cstdio>
 2 # include <iostream>
 3 
 4 using namespace std;
 5 
 6 int T;
 7 long long x,f[50];
 8 int i;
 9 
10 int main()
11 {
12     f[0]=0;
13     f[1]=f[2]=1;
14     for (int i=3;i<=45;++i)
15         f[i]=f[i-1]+f[i-2];
16     scanf("%d",&T);
17     while (T--)
18     {
19         scanf("%lld",&x);
20         bool F=false;
21         for (int i=0;i<=45;++i)
22             for (int j=0;j<=45;++j)
23                 if(f[i]*f[j]==x) F=true;
24         if(F)
25             printf("TAK\n");
26         else
27             printf("NIE\n");
28     }
29     return 0;
30 }
Iloczyn

 

  解方程:https://www.luogu.org/problemnew/show/P2312

  题意概述:求一个$n$次方程在$[1,m]$,范围内的整数解。$n<=100,m<=1e6,a_i<=10^{1000}$

  首先可以想到一个小数据下的做法:枚举每个$x$,代入试一试,只能得30分。然后就是瞎搞时间了:一个普通方程可以认为是一个对于无限大取模的同余方程,所以也可以把无限大变小,尝试一下在模某些大数情况下方程是否成立,如果成立,那很可能在模无限的意义下也成立,建议取一个大一点的质数以提高正确率,也可以多选几个,但是容易超时。(如何看待NOIP出现正解像骗分的题目)。

  
 1 // luogu-judger-enable-o2
 2 # include <cstdio>
 3 # include <iostream>
 4 # include <string>
 5 # include <cstring>
 6 # define mod 998244353
 7 # define R register int
 8 
 9 int n,m;
10 long long a[109];
11 int ans[1000009],cnt;
12 std::string s;
13 
14 inline bool check (int x)
15 {
16     long long ans=0,s=1;
17     for (int i=0;i<=n;++i)
18     {
19         ans=(ans+s*a[i]+mod)%mod;
20         s=(s*x+mod)%mod;
21     }
22     if(ans==0) return true;
23     return false;
24 }
25 
26 inline long long read()
27 {
28     int f=1;
29     long long x=0;
30     char c=getchar();
31     while (!isdigit(c))
32     {
33         if(c=='-') f=-f;
34         c=getchar();
35     }
36     while (isdigit(c))
37     {
38         x=(x*10+c-'0')%mod;
39         c=getchar();
40     }
41     return x*f;
42 }
43 
44 int main()
45 {
46     scanf("%d%d",&n,&m);
47     for (R i=0;i<=n;++i)
48         a[i]=read();
49     for (R i=1;i<=m;++i)
50         if(check(i))
51             ans[++cnt]=i;
52     printf("%d\n",cnt);
53     for (R i=1;i<=cnt;++i)
54         printf("%d\n",ans[i]);
55     return 0;
56 }
解方程

 

  找爸爸:无

  听名字就像胡策题...这是高二学长们胡策的T1,感觉非常有趣.

   

  题意概述:给出一棵$n$个节点的树,$q$个询问,每次询问$a$号点的$b$级祖先.$n<=10^7,q<=10^6$

  题出的好!覆盖知识点广,题目有着切合实际的背景,解法比较自然。给出题人点赞!

  明天再补吧。

---shzr

posted @ 2018-05-21 18:58  shzr  阅读(212)  评论(0编辑  收藏  举报