热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

2017.7.21夏令营清北学堂解题报告

预计分数:60+30+090划水实际分数:90+30+20140rank5雷蛇鼠标一句话总结:今天该买彩票!T1:题目描述从前有一个?

预计分数:

60+30+0=90=划水

实际分数:

90+30+20=140=rank5=雷蛇鼠标

一句话总结:今天该买彩票!

 

T1:

题目描述

从前有一个?行?列的网格。

现在有?种颜色,第?种颜色可以涂??格,保证

Σ︀ ?? = ? * ?。

需要你对这个网格图进行着色,你必须按照从上到下,每一行内从左到右

的顺序进行着色,并且在用完一种颜色前你不能换颜色(当然颜色的使用顺序

是随意的)。

每个相邻的相同色块可以获得1分,问在给定的规则下进行着色所能获得的

最高分是多少。

多组数据。

输入输出格式

输入格式:
从文件diyiti.in中读入数据。

第一行一个整数?表示数据组数。

对于每组数据,第一行三个整数?, ?, ?表示网格的大小和颜色的数量。

之后一行?个数,第?个数表示第?种颜色可以涂的格数。

输出格式:
将答案输出到diyiti.out。

对于每组数据一个数???,表示能获得的最高分。

输入输出样例

输入样例#12
3 3 4
1 2 2 4
4 2 4
1 2 2 3
输出样例#15
4
说明

【样例解释】

第一组数据

1 2 2 3 3 4 4 4 4 第二组数据

1 4 4 4 2 2 3 3 对于30%的数据,1 ≤ ?, ? ≤ 10, 1 ≤ ? ≤ 2

对于60%的数据,1 ≤ ?, ? ≤ 1000, 1 ≤ ? ≤ 3

对于100%的数据,1 ≤ ?, ? ≤ 100000, 1 ≤ ? ≤ 4, ?? ≥ 1, ? ≤ 10

3
T1

感觉这题好鬼畜,从来没有见过这种类型的题,一开始噼里啪啦的敲了90+行的暴力,

不出所料只能过30%的数据,没办法,只能留着对拍了。。。。

后来发现了一个公式:

当p%m==0的时候的方案数是:((m-1)+(p/m-1)*(m*2-1));

然后特判一下每种情况搞一搞就好了,

预计能过60%的数据,

但是最后居然得了90分,,

而且另外的十分不知道怎么丢的,,,,=.=

暴力:

 

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 using namespace std;
  7 const int MAXN=100001;
  8 const int maxn=0x7ffff;
  9 void read(int &n)
 10 {
 11     char c='+';int x=0;bool flag=0;
 12     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
 13     while(c>='0'&&c<='9')
 14     x=(x<<1)+(x<<3)+c-48,c=getchar();
 15     flag==1?n=-x:n=x;
 16 }
 17 int T;
 18 int n,m,colornum;
 19 int color[MAXN];
 20 int map[MAXN][6];
 21 int ans=0;
 22 int xx[5]={-1,+1,0,0};
 23 int yy[5]={0,0,-1,+1};
 24 int vis[MAXN];
 25 void dfs(int used,int bh,int coloruse,int x,int y)
 26 //  使用了的颜色   当前点的编号  当前已使用 
 27 {
 28     if(used==colornum&&coloruse==color[bh])
 29     {
 30         int now=0;
 31         for(int i=1;i<=n;i++)
 32             for(int j=1;j<=m;j++)
 33                 for(int k=0;k<4;k++)
 34                 {
 35                     int wx=i+xx[k];
 36                     int wy=j+yy[k];
 37                     if(wx>=1&&wx<=n&wy>=1&&wy<=m)
 38                         if(map[i][j]==map[wx][wy])
 39                             now++;
 40                 }
 41                     
 42         ans=max(ans,now/2);
 43         return ;
 44     }
 45     int wx,wy;
 46     if(y==m)    {    wy=1;wx=x+1;}
 47     else    {    wy=y+1;    wx=x;    }
 48     if(coloruse==color[bh])
 49     {
 50         vis[bh]=1;
 51         for(int i=1;i<=colornum;i++)
 52         {
 53             if(!vis[i])
 54             {
 55             //    vis[i]=1;
 56                 map[wx][wy]=i;
 57                 dfs(used+1,i,1,wx,wy);
 58                 map[wx][wy]=0;
 59             //    vis[i]=0;
 60             }
 61         }
 62         vis[bh]=0;
 63     }
 64     else
 65     {
 66         map[wx][wy]=bh;
 67         dfs(used,bh,coloruse+1,wx,wy);
 68         map[wx][wy]=0;
 69     }
 70         
 71 }
 72 int main()
 73 {
 74 //    freopen("diyiti.in","r",stdin);
 75 //    freopen("diyiti.out","w",stdout);
 76     //
 77     read(T);
 78     while(T--)
 79     {
 80         memset(vis,0,sizeof(vis));
 81         memset(map,0,sizeof(map));
 82         memset(color,0,sizeof(color));
 83         ans=0;
 84         read(n);read(m);read(colornum);
 85         if(n>=0)
 86         {
 87             for(int i=1;i<=colornum;i++)
 88                 read(color[i]);
 89             for(int i=1;i<=colornum;i++)
 90             {
 91             //    vis[color[i]]=1;
 92                 map[1][1]=i;
 93                 dfs(1,i,1,1,1);
 94                 map[1][1]=0;
 95                 //vis[color[i]]=0;
 96             }
 97             printf("%d\n",ans);    
 98         }
 99         else
100         {
101             int p;
102             if(colornum==n*m) 
103             {
104                 for(int i=1;i<=colornum;i++)
105                     read(p);
106                 printf("0\n");
107                 continue;
108             }
109             if(m==1) 
110             {
111                 for(int i=1;i<=colornum;i++) 
112                 {
113                     read(p);
114                     ans+=p-1;//上下两个相邻 
115                 }
116             } 
117             else if(m==2) 
118             {
119                 for(int i=1;i<=colornum;i++) 
120                 {
121                     read(p);
122                     if(p==1) 
123                         continue;// 没有相邻 
124                     else 
125                         ans+=((m-1)+(p/m-1)*(m*2-1))+p%m;
126                 }
127             } 
128             else if(m==3) 
129             {
130                 for(int i=1;i<=colornum;i++) 
131                 {
132                     read(p);
133                     if(p==1) 
134                         continue;
135                     if(p<m) 
136                         if(p%2)
137                             ans+=p-1;// 左右相邻 
138                         else
139                             ans+=p-2;
140                     else 
141                     {
142                         ans+=((m-1)+(p/m-1)*(m*2-1));
143                         int remain=p%3;
144                         if(remain!=0)
145                             ans+=(remain*2-1);
146                     }
147                 }
148             } 
149             else if(m==4) 
150             {
151                 for(int i=1;i<=colornum;i++) 
152                 {
153                     read(p);
154                     if(p==1) 
155                         continue;
156                     if(p<m) 
157                         ans+=p-1;
158                     else 
159                     {
160                         ans+=((m-1)+(p/m-1)*(m*2-1));
161                         int remain=p%4;
162                         if(remain!=0)
163                             ans+=(remain*2-1);
164                     }
165                 }
166             }
167             printf("%d\n",ans);
168         }
169     }
170     return 0;
171 }
T1暴力

 

 1 #include
 2 using namespace std;
 3 int T,n,m,S,a[100010],p[5],ans;
 4 int main(){
 5     freopen("diyiti3.in","r",stdin);
 6     freopen("diyiti3.out","w",stdout);
 7     scanf("%d",&T);
 8     while(T--){
 9         memset(p,0,sizeof(p));
10         ans=0;
11         scanf("%d%d%d",&n,&m,&S);
12         for(int i=1;i<=S;i++){
13             scanf("%d",&a[i]);
14             p[a[i]%m]++;
15             if(a[i]>=m)ans+=(a[i]/m*(2*m-1)-m+a[i]%m+max(0,a[i]%m-1));
16             else ans+=a[i]-1;
17         }
18         if(m==3){
19             if(p[2]>p[1])ans-=(p[2]-p[1])/3;
20         }else if(m==4){
21             if(p[3]>p[1])ans-=(p[3]-p[1])/2;
22         }
23         printf("%d\n",ans);
24     }
25 }
T1正解

 

T2:

 

题目描述

在纸上有一个长为?的数列,第?项值为??。

现在小A想要在这些数之间添加加号或乘号。问对于不同的2?−1种方案,

所有答案的和是多少?

由于数据范围较大,所以输出对1000000007取模的结果。

输入输出格式

输入格式:
从文件dierti.in中读入数据。

输入第一行一个整数?表示数列的长度。

之后一行?个整数,第?个整数表示数列的第?项??。

输出格式:
输出到文件dierti.out中。

?行,第?行表示第?个询问的答案对1000000007取模的结果。

输入输出样例

输入样例#13
1 2 4
输出样例#130
说明

对于30%的数据,1 ≤ ? ≤ 10, 1 ≤ ?? ≤ 10

对于另外30%的数据,1 ≤ ? ≤ 1000, ?? = 1

4 对于90%的数据,1 ≤ ? ≤ 1000, 1 ≤ ?? ≤ 105

对于100%的数据,1 ≤ ? ≤ 100000, 1 ≤ ?? ≤ 109
T2

 

第一眼:DP,十分不可做。。

第二眼:30%的暴力好像可以搞一搞

第三眼:其余30%的数据好像可以用组合数搞一搞

第三眼:最后40%不要了,开始搞吧,

 

于是噼里啪啦敲完第一题的鬼畜代码(就是实现个加减法我连队列都用上了,,,,)

然后开始搞其余30%,其实这时候剩下的时间已经不多了,于是想也没想就直接暴力就组合数。

暴力敲的应该是对的,但是因为求组合数牵扯到除法而且这道题还要取mod,当时想到需要求逆元了然而这时候也就还剩十几分钟所以果断放弃

后来有大佬说全是一的情况只要把所有数的平方全加起来再加个什么东西就可以,,,,,

 

正解:动规,用f[i]表示第i轮的所有情况的和,然后就不会了,,,,

暴力:

 

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 using namespace std;
 7 const int MAXN=100001;
 8 const int maxn=0x7ffff;
 9 const int mod=1000000007;
10 void read(int &n)
11 {
12     char c='+';int x=0;bool flag=0;
13     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
14     while(c>='0'&&c<='9')
15     x=(x<<1)+(x<<3)+c-48,c=getchar();
16     flag==1?n=-x:n=x;
17 }
18 int n;
19 int a[MAXN];
20 int flag=0;
21 int ans;
22 int how[MAXN];
23 int num=1;
24 int tot=0;
25 void calc()
26 {
27     queue<int>q;
28     for(int i=1;i<=num;i++)
29     {
30         if(how[i]==2)
31         {
32             int now=1;
33             while(how[i]==2)
34             {
35                 now=(now*a[i])%mod;
36                 i++;
37             }
38             now=(now*a[i])%mod;
39             q.push(now);
40         }
41         else
42             q.push(a[i]);
43     }
44     while(q.size()!=0)
45     {
46         ans=(ans+q.front())%mod;
47         q.pop();
48     }
49 }
50 void dfs(int pos)
51 {
52     if(pos==n-1)
53     {    
54         tot++;
55         calc();
56         return ;
57     }
58     
59     for(int i=1;i<=2;i++)
60     {
61         how[num++]=i;
62         dfs(pos+1);
63         how[--num]=0;
64     }
65 }
66 int jc(int num)
67 {
68     if(num==0)
69         return 1;
70     else 
71         return (num*(jc(num-1)))%mod;
72 }
73 int main()
74 {
75     freopen("dierti.in","r",stdin);
76     freopen("dierti.out","w",stdout);
77     read(n);
78     for(int i=1;i<=n;i++)
79     {    read(a[i]);    if(a[i]==1)        flag++;    }
80     if(flag==n)
81     {
82         int p=jc(n-1)%mod; 
83         for(int i=1;i<=n-1;i++)// 放多少个* 
84         {
85             int hh=(p/(jc(i)*jc(n-i-1)))%mod;
86             ans=ans+((n-i)*hh)%mod;
87         }
88         printf("%d",(ans+n)%mod);
89     }
90     else
91     {
92         dfs(0);
93         printf("%d",ans%mod);    
94     }
95     return 0;
96 }
T2暴力

 

 1 #include
 2 #define mod 1000000007 
 3 #define N 100010
 4 using namespace std;
 5 int T,n,i,a[N],g[N],f[N],sum,sum1;
 6 int powmod(int x,int y){
 7     int ans=1;
 8     for(;y;y>>=1,x=1ll*x*x%mod)
 9         if(y&1)ans=1ll*ans*x%mod;
10     return ans;
11 }
12 int main(){
13     scanf("%d",&n);
14     sum=0;sum1=g[0]=1;
15     for(i=1;i<=n;i++){
16         scanf("%d",&a[i]);
17         g[i]=1ll*g[i-1]*a[i]%mod;
18         f[i]=(sum+1ll*g[i]*sum1)%mod;
19         sum=(sum+f[i])%mod;
20         sum1=(sum1+1ll*powmod(2,(i-1))*powmod(g[i],mod-2))%mod;
21     }
22     printf("%d\n",f[n]);
23 }
T2正解

 

 

 

T3

 

题目描述

有一个? * ?的网格图,其中每个格子都有一个数。

设??为第?行的最小值,??为第?列的最大值,我们称一个网格是好的,当

且仅当满足

max(?1, ...,??) = min(??, ...,??)

现在问最少改变多少个数可以使得这个网格是好的。

输入输出格式

输入格式:
从文件disanti.in中读入数据。

第一行一个整数?。

之后?行,每行?个数,描述这个矩阵。

输出格式:
输出到文件disanti.out中。

一个数???,表示最少需要改变的数的个数。

输入输出样例

暂无测试点
说明

对于30%的数据,1 ≤ ?, ?? ≤ 10

对于另外30%的数据,1 ≤ ? ≤ 100, 1 ≤ ?? ≤ 3

对于90%的数据,1 ≤ ? ≤ 100, 1 ≤ ?? ≤ 105

对于100%的数据,1 ≤ ? ≤ 1000, 1 ≤ ?? ≤ 10
T3

 

这题,,是我有史以来的最完美的、

说一下我的思路:

当n>100时,cout<

else cout<<2;

然后,就得了20分。

为什么是2不是3呢?

我们想,对于一个n<=10的矩阵,

改一次会不会太少了?

所以

改两次!

 

正解:我们假设一个i是要找的答案。

那么这个i就要满足&……¥*……(&(*#@!&#(*@……¥(*&#%2

 

 

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 using namespace std;
 7 const int MAXN=1001;
 8 const int maxn=0x7ffff;
 9 void read(int &n)
10 {
11     char c='+';int x=0;bool flag=0;
12     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
13     while(c>='0'&&c<='9')
14     x=(x<<1)+(x<<3)+c-48,c=getchar();
15     flag==1?n=-x:n=x;
16 }
17 int map[MAXN][MAXN];
18 int main()
19 {
20     freopen("disanti.in","r",stdin);
21     freopen("disanti.out","w",stdout);
22     int n;
23     read(n);
24     for(int i=1;i<=n;i++)
25         for(int j=1;j<=n;j++)
26             read(map[i][j]);
27     if(n<=10)
28     printf("2");
29     else if(n<=100&&n<=1000)
30     printf("20");
31     else
32     printf("200");
33     return 0;
34 }
骗分

 

 1 #include
 2 using namespace std;
 3 int n,m,i,x,A[1100],B[1100],C[1100000],ans,j,k,SS[1100000],TT[1100000];
 4 pair<int,int>a[1100000];
 5 int main(){
 6     scanf("%d",&n);
 7     m=n*n;
 8     ans=n*2-1;
 9     for(i=0;i)
10         scanf("%d",&a[i].first),a[i].secOnd=i;
11     sort(a,a+m);
12     for(i=0;ij){
13         TT[i]=TT[i-1];
14         for(j=i;a[j].first==a[i].first&&j){
15             x=a[j].second;
16             B[x%n]++;
17             TT[i]=max(TT[i],B[x%n]);
18         }
19         for(k=i;kTT[i];
20     }
21     memset(A,0,sizeof(A));
22     for(i=m-1;i>=0;i=j){
23         SS[i]=SS[i+1];
24         for(j=i;a[j].first==a[i].first&&j>=0;j--){
25             x=a[j].second;
26             A[x/n]++;
27             SS[i]=max(SS[i],A[x/n]);
28         }
29         for(k=i;k>j;k--)SS[k]=SS[i];
30     }
31     for(i=0;i)
32         if(n-SS[i]+n-TT[i]TT[i];
33     printf("%d\n",ans);
34 }
T3

 

 

 

 

总结:

还算考的不错,但这次考试能得rank5,运气成分真的是非常的大。

T1有七八个人A掉,

T2有一个人A掉 ,五六个90分,

说明自己的提升空间还很大。

加油!

2017 noip 创造奇迹!

 

 


推荐阅读
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了SPOJ2829题目的解法及优化方法。题目要求找出满足一定条件的数列,并对结果取模。文章详细解释了解题思路和算法实现,并提出了使用FMT优化的方法。最后,对于第三个限制条件,作者给出了处理方法。文章最后给出了代码实现。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文主要介绍了gym102222KVertex Covers(高维前缀和,meet in the middle)相关的知识,包括题意、思路和解题代码。题目给定一张n点m边的图,点带点权,定义点覆盖的权值为点权之积,要求所有点覆盖的权值之和膜qn小于等于36。文章详细介绍了解题思路,通过将图分成两个点数接近的点集L和R,并分别枚举子集S和T,判断S和T能否覆盖所有内部的边。文章还提到了使用位运算加速判断覆盖和推导T'的方法。最后给出了解题的代码。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
滒娶伱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有