SIDA-Day1/20200803/test

T1 apple

【问题描述】

陶陶家门前有一块 n 行 m 列的耕地
有些格子可以种苹果(用 1 表示),一些无法种苹果(用 0 表示),并且相邻格子无法都种苹果
陶陶想知道有多少种种植方案(一颗也不种也是可以的)

【输入文件】

输入文件为 apple.in
第一行包含用空格隔开的两个整数 n,m
接下来 n 行每行 m 个数,为1或0,表示能否种植

【输出文件】

输出文件为 apple.out
共一行,一个整数ans,表示方案数。

【输入样例1】

1 5
1 1 1 1 1

【输出样例1】

 13

【输入样例2】

1 10
1 1 1 1 0 1 1 0 1 1

【输出样例2】

 72

【输入样例3】

2 10
1 1 0 1 1 1 0 1 1 1
1 0 1 1 1 1 0 0 1 0

【输出样例3】

1305

【数据规模和约定】

对于前 30%的数据,满足 n=1,所有格子都能种苹果。
对于另外 20%的数据,满足 n=1。
对于另外 20%的数据,保证每行只有一个位置能种苹果。
对于 100%的数据,满足 n<=2,m<=10

 

60分代码

 1 #include<cstdio>
 2 using namespace std;
 3 const int MAXN=2,MAXM=10;
 4 int n,m,a[MAXN][MAXM],ans;
 5 bool b[MAXN+2][MAXM+2];
 6 int ct[11]={1,2,3,5,8,13,21,34,55,89,144};
 7 int main()
 8 {
 9     freopen("apple.in","r",stdin);
10     freopen("apple.out","w",stdout);
11     scanf("%d%d",&n,&m);
12     for(int i=1;i<=n;i++)
13         for(int j=1;j<=m;j++)
14             scanf("%d",&a[i][j]);
15    if(n==1)//n=1
16    {
17         for(int i=1;i<=m;i++)
18             ans=1;
19             for(int i=1,j=0;i<=m+1;i++)
20             {
21                 if(a[1][i]==0)
22                 {
23                     ans*=ct[j];
24                     j=0; 
25                 }
26                 else
27                 {
28                     j++;
29                 }
30             }
31             printf("%d",ans);
32             return 0;
33    }
34     else//n==2
35     {
36         int pos;
37         for(int i=1;i<=m;i++)
38             if(a[1][i]==1)
39                 pos=i;
40         if(a[2][pos]==1)
41         {
42             printf("3");
43             return 0;
44         }
45         else
46         {
47             printf("4");
48             return 0;
49         }
50         
51     }
52     return 0;
53 }
查看代码

//不知道为什么9个1过不了,不然就70分

思路:
当n=1,全部为1时,找规律可得为斐波那契数列,故记录ct[]为斐波那契数直接调用
当n=1,不全为1时,以0拆分为若干段,每段的情况相乘即为答案
当每行只有一个位置有苹果时,判断是否在同一列,在同一列答案为3,否则答案为4
理论上能骗到70分

AC代码

 1 //二进制模拟
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 #define rep(i,h,t) for (int i=h;i<=t;i++)
 6 #define me(x) memset(x,0,sizeof(x))
 7 int a[30][30],p[30][30],n,m;
 8 int main()
 9 {
10     freopen("apple.in","r",stdin);
11     freopen("apple.out","w",stdout);
12     ios::sync_with_stdio(false);//加速cin,cout
13     cin>>n>>m;
14     int num=0;
15     rep(i,1,n)
16      rep(j,1,m)
17      { 
18        cin>>a[i][j];
19        if (a[i][j]) num++;//统计可种植点数
20      }
21     int ans=0;
22     rep(i,0,(1<<num)-1)//从num个0模拟到num个1
23     {
24         me(p);//重置种植情况
25         rep(j,1,num)//num个点的种植情况存入p数组
26         {
27             int k=(i>>(j-1))&1;//取第j位
28             int cnt=0,i1,j1;
29             for (i1=1;i1<=n;i1++)
30             {
31               for (j1=1;j1<=m;j1++)
32               {
33                 if (a[i1][j1]) cnt++;
34                 if (cnt==j) break;//找到第cnt个点的坐标i1,j1时跳出
35               }
36                if (cnt==j) break;
37             }
38             p[i1][j1]=k;//种植情况存入
39         }
40         bool tt=1;//初始设为合法
41         rep(i,1,n)
42           rep(j,1,m)
43           {
44             if (j>1&&p[i][j]&&p[i][j-1]) tt=0;//横向判断非法
45             if (i>1&&p[i][j]&&p[i-1][j]) tt=0;//纵向判断非法
46             if (!tt) break;//非法即跳出
47           }
48         if (tt) ans++;//合法则记录
49     }
50     cout<<ans<<endl;
51     return 0;
52 }
53 //时间复杂度:O(2^(n*m))<=2^20≈2e7
查看代码

T2 music

【问题描述】

一共唱 n 个音符,每个音符持续 b[i]个时间。 比如第一个音符,在 0~b[1]-1 时间内歌唱。 比如第二个音符,在 b[1]~b[1]+b[2]-1 时间内歌唱。 以此类推。。。
现在有 q 组询问,每组询问有一个时刻 t。
求对于每一个询问 t,赤羽所唱的音符。

【输入文件】

输入文件为 music.in。
第一行两个整数 n,q。
第2~n+1行 n 个数表示每个音符持续的时间。

【输出文件】

输出文件为 music.out。 共n行。 每行输出对应的音符

【输入样例1】

3 5 
2 
1 
3 
2 
3 
4 
0 
1

【输出样例1】

2
3
3
1
1

【数据规模和约定】
对于 30%的数据 n<=1000,b[i]<=1000,q=1
另外 30%的数据 n<=1000,b[i]<=10000,q<=10000
对于 100%的数据 n<=10000,b[i]<=10000,q<=1e5

AC代码

#include<cstdio>
#include<algorithm>
const int MAXN=10000,MAXQ=1e5;
int n,q,b[MAXN+2],a[MAXN+2];
using namespace std;
int main()
{
    freopen("music.in","r",stdin);
    freopen("music.out","w",stdout);
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
        a[i]=a[i-1]+b[i];//唱完第i个音符结束的时间
        if(i==1)
            a[i]--;
    }
    for(int i=1;i<=q;i++)
    {
        int ask;
        scanf("%d",&ask);
        int pos=lower_bound(a+1,a+n+1,ask)-a;
        printf("%d
",pos);
    }
}
查看代码

//STL直接带舒服

total:160/rank:1

原文地址:https://www.cnblogs.com/Ender-hz/p/13430388.html