NOIP2015 pj

达成成就!——尝试不看题解的情况下用cpp打完了一套NOIP pj

题目全部在luogu上——

P2669 金币

题目描述

国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。

请计算在前K天里,骑士一共获得了多少金币。

输入输出格式

输入格式:

输入文件只有1行,包含一个正整数K,表示发放金币的天数。

输出格式:

输出文件只有1行,包含一个正整数,即骑士收到的金币数。

输入输出样例

输入样例#1:
6
输出样例#1:
14
输入样例#2:
1000
输出样例#2:
29820

说明

【输入输出样例 1 说明】

骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,

每天收到三枚金币。因此一共收到 1+2+2+3+3+3=14 枚金币。

对于 100%的数据, 1 ≤ K ≤ 10,000。

Solution

直接模拟

 1 #include<cstdio>
 2 using namespace std;
 3 
 4 int main(){
 5   //freopen("1.in","r",stdin);
 6   //freopen("1.out","w",stdout);
 7 
 8   int n;
 9   int i=0;
10   int ans=0;
11 
12   scanf("%d",&n);
13 
14   while (n>0)
15   {
16     n-=++i;
17     ans=ans+i*i;
18   }
19 
20   ans=ans-(0-n)*i;
21   printf("%d",ans);
22 
23   fclose(stdin);  fclose(stdout);
24   return 0;
25 }
View Code

P2670 扫雷游戏

题目描述

扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。

现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。

注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

输入输出格式

输入格式:

输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。

接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。

输出格式:

输出文件包含n行,每行m个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

输入输出样例

输入样例#1:
3 3
*??
???
?*?
输出样例#1:
*10
221
1*1
输入样例#2:
2 3
?*?
*??
输出样例#2:
2*1
*21

说明

对于 100%的数据, 1≤n≤100, 1≤m≤100。

Solution

还是模拟。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 int main(){
 5   char c[100][100];
 6   int apple[102][102];
 7   memset(apple,0,sizeof(apple));
 8   freopen("1.in","r",stdin);
 9   freopen("1.out","w",stdout);
10 
11   int n,m;
12   scanf("%d %d
",&n,&m);
13 
14   for (int i=1;i<=n;i++){
15    for (int j=1;j<=m;j++)
16    {
17     scanf("%c",&c[i][j]);
18     if (c[i][j]=='*'){
19       apple[i-1][j-1]++;
20       apple[i+1][j+1]++;
21       apple[i][j-1]++;
22       apple[i-1][j]++;
23       apple[i][j+1]++;
24       apple[i+1][j]++;
25       apple[i-1][j+1]++;
26       apple[i+1][j-1]++;
27     }
28     }
29     scanf("
");
30    }
31   for (int i=1;i<=n;i++)
32   {
33     for (int j=1; j<=m;j++){
34     if (c[i][j]=='?') printf("%d",apple[i][j]);
35       else printf("*");
36     }
37     printf("
");
38   }
39 
40 }
View Code

P2671 求和

题目描述

一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色color_i用[1,m]当中的一个整数表示),并且写了一个数字number_i。

定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元

组要求满足以下两个条件:

1.xyz是整数,x<y<z,y-x=z-y

2.colorx=colorz

满足上述条件的三元组的分数规定为(x+z)*(number_x+number_z。整个纸带的分数

规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以10,007所得的余数即可。

输入输出格式

输入格式:

第一行是用一个空格隔开的两个正整数n和m,n表纸带上格子的个数,m表纸带上颜色的种类数。

第二行有n用空格隔开的正整数,第i数字number表纸带上编号为i格子上面写的数字。

第三行有n用空格隔开的正整数,第i数字color表纸带上编号为i格子染的颜色。

输出格式:

共一行,一个整数,表示所求的纸带分数除以10,007所得的余数。

输入输出样例

输入样例#1:
6 2
5 5 3 2 2 2
2 2 1 1 2 1
输出样例#1:
82
输入样例#2:
15 4
5 10 8 2 2 2 9 9 7 7 5 6 4 2 4
2 2 3 3 4 3 3 2 4 4 4 4 1 1 1
输出样例#2:
1388

说明

【输入输出样例 1 说明】

纸带如题目描述中的图所示。

所有满足条件的三元组为: (1, 3, 5), (4, 5, 6)。

所以纸带的分数为(1 + 5)*(5 + 2) + (4 + 6)*(2 + 2) = 42 + 40 = 82。

对于第 1 组至第 2 组数据, 1 ≤ n ≤ 100, 1 ≤ m ≤ 5;

对于第 3 组至第 4 组数据, 1 ≤ n ≤ 3000, 1 ≤ m ≤ 100;

对于第 5 组至第 6 组数据, 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000,且不存在出现次数

超过 20 的颜色;

对 于 全 部 10 组 数 据 , 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, 1 ≤ color_i ≤ m,1≤number_i≤100000

Solution

先按颜色排序,把同颜色的归为一类,然后根据奇偶性瞎搞就可以了,取模打错了好多次。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 long long n,m;
 7 long long color[100001],num[100001],id[100001];
 8 const long long moding=10007;
 9 
10 void swap(long long &aa,long long &bb){  //swap function
11  long long tt;
12   tt=aa;
13   aa=bb;
14   bb=tt;
15 }
16 
17 void qsort(long long l,long long r){
18  long long i=l,j=r,mi=id[(l+r)/2];
19  long long  mm=color[(l+r)/2];
20 
21   do
22   {
23     while ((color[i]<mm)||(color[i]==mm&&id[i]<mi)) i++;
24     while ((color[j]>mm)||(color[j]==mm&&mi<id[j])) j--;  //double keys qsort
25     if (i<=j){
26       swap(color[i],color[j]);
27       swap(num[i],num[j]);
28       swap(id[i],id[j]);
29       i++;j--;
30     }
31   }while (i<=j);
32 
33   if (l<j) qsort(l,j);
34   if (i<r) qsort(i,r);
35 }
36 
37 int partit(long long  l,long long r){
38   // long long odd_num[100001],no_num[100001];
39  //  long long odd_color[100001],no_color[100001];
40   long long odd=0,no=0,odd_sum=0,no_sum=0,tmp=0;
41 
42    for (long long j=l;j<=r;j++)
43     if (id[j]%2==1) {
44        odd++;
45     odd_sum+=id[j];
46     //    odd_num[odd]=num[j];   odd_color[odd]=color[j];
47     }
48     else {
49        no++;
50        no_sum+=id[j];
51    //    no_num[no]=num[j];    no_color[no]=color[j];
52     }
53     for (long long j=l;j<=r;j++)
54     if (id[j]%2==1) {
55         if (odd>1)  tmp=((tmp % moding)+(num[j]*(odd_sum+id[j]*(odd-2)))%moding)%moding;
56       //  printf("%lld 
",tmp);    printf("----
");
57     }
58     else if (no>1)  tmp=((tmp % moding)+(num[j]*(no_sum+id[j]*(no-2)))%moding)%moding;
59 //  printf("%lld 
",tmp);  printf("======
");
60    return tmp % moding;
61 }
62 int main(){
63   long long ll=1,ans=0;
64 
65   freopen("sum.in","r",stdin);
66   freopen("sum.out","w",stdout);
67 
68   scanf("%lld %lld
",&n,&m);
69   for (long long i=1;i<=n;i++) scanf("%lld ",&num[i]);
70   for (long long i=1;i<=n;i++) scanf("%lld ",&color[i]);
71   for (long long i=1;i<=n;i++) id[i]=i;
72       
73   qsort(1,n);
74 
75   for (long long i=2;i<=n+1;i++)
76      if (color[i]!=color[i-1])
77      {
78          ans=((ans % moding)+partit(ll,i-1))%moding;
79          ll=i;
80      }
81   printf("%lld",ans);
82   return 0;
83 }
View Code

P2672 推销员

题目描述

阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有N家住户,第i家住户到入口的距离为Si米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的X家住户推销产品,然后再原路走出去。

阿明每走1米就会积累1点疲劳值,向第i家住户推销产品会积累Ai点疲劳值。阿明是工作狂,他想知道,对于不同的X,在不走多余的路的前提下,他最多可以积累多少点疲劳值。

输入输出格式

输入格式:

第一行有一个正整数N,表示螺丝街住户的数量。

接下来的一行有N个正整数,其中第i个整数Si表示第i家住户到入口的距离。数据保证S1≤S2≤…≤Sn<10^8。

接下来的一行有N个正整数,其中第i个整数Ai表示向第i户住户推销产品会积累的疲劳值。数据保证Ai<10^3。

输出格式:

输出N行,每行一个正整数,第i行整数表示当X=i时,阿明最多积累的疲劳值。

输入输出样例

输入样例#1:
5
1 2 3 4 5
1 2 3 4 5
输出样例#1:
15
19
22
24
25
输入样例#2:
5
1 2 2 4 5
5 4 3 4 1
输出样例#2:
12
17
21
24
27

说明

【输入输出样例1说明】

X=1:向住户5推销,往返走路的疲劳值为5+5,推销的疲劳值为5,总疲劳值为15。

X=2:向住户4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为4+5,总疲劳值为5+5+4+5=19。

X=3:向住户3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值3+4+5,总疲劳值为5+5+3+4+5=22。

X=4:向住户2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值2+3+4+5,总疲劳值5+5+2+3+4+5=24。

X=5:向住户1、2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值1+2+3+4+5,总疲劳值5+5+1+2+3+4+5=25。

【输入输出样例2说明】

X=1:向住户4推销,往返走路的疲劳值为4+4,推销的疲劳值为4,总疲劳值4+4+4=12。

X=2:向住户1、4推销,往返走路的疲劳值为4+4,推销的疲劳值为5+4,总疲劳值4+4+5+4=17。

X=3:向住户1、2、4推销,往返走路的疲劳值为4+4,推销的疲劳值为5+4+4,总疲劳值4+4+5+4+4=21。

X=4:向住户1、2、3、4推销,往返走路的疲劳值为4+4,推销的疲劳值为5+4+3+4,总疲劳值4+4+5+4+3+4=24。或者向住户1、2、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为5+4+4+1,总疲劳值5+5+5+4+4+1=24。

X=5:向住户1、2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为5+4+3+4+1,

总疲劳值5+5+5+4+3+4+1=27。

【数据说明】

对于20%的数据,1≤N≤20;

对于40%的数据,1≤N≤100;

对于60%的数据,1≤N≤1000;

对于100%的数据,1≤N≤100000。

Solution

刚开始测了一下二维的暴力只拿了40;

于是开始各种奇怪的东西,=>

首先我们可以发现在找x个买家时,我们可以从x-1的推过来,于是很明显的阶段性,决策有已经走了的和后面的,这里来个堆维护最大值就可以了,

但是我作死维护了两棵线段树。。。。。

然后还学会了gdb。。。。

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #define ll long long
  5 #define pr(a) for(long long i=1;i<=n;i++) printf("%lld ",a[i]);printf("
");
  6 const ll maxn=100000+2;
  7 using namespace std;
  8 
  9 
 10 typedef struct {
 11     ll val,left,right;
 12 }arr;
 13 
 14 //define var =====================
 15 
 16 ll n,ap;
 17 arr tree[4*maxn-1],tree2[4*maxn-1];
 18 ll dis[maxn],tir[maxn],diss[maxn];
 19 bool check[maxn];
 20 
 21 //main codes =====================
 22 
 23 void swap(long long &aa,long long &bb){  //swap function
 24  long long tt;
 25   tt=aa;
 26   aa=bb;
 27   bb=tt;
 28 }
 29 
 30 void qsort(long long l,long long r){
 31  long long i=l,j=r;
 32  long long  mm=dis[(l+r)/2];
 33 
 34   do
 35   {
 36     while (dis[i]<mm) i++;
 37     while (dis[j]>mm) j--;  //double keys qsort
 38     if (i<=j){
 39       swap(dis[i],dis[j]);
 40       swap(tir[i],tir[j]);
 41       i++;j--;
 42     }
 43   }while (i<=j);
 44 
 45   if (l<j) qsort(l,j);
 46   if (i<r) qsort(i,r);
 47 }
 48 
 49 
 50 void init(){
 51     //freopen("1.in","r",stdin);
 52    // freopen("1.out","w",stdout);
 53 
 54     memset(check,1,sizeof(check));
 55     scanf("%lld",&n);
 56 
 57     for (ll i=1;i<=n;i++) scanf("%lld ",&dis[i]);
 58     for (ll i=1;i<=n;i++) scanf("%lld ",&tir[i]);
 59 
 60     tir[0]=0;  dis[0]=0;
 61     qsort(1,n);
 62 }
 63 
 64 void build( ll l , ll r , ll w){
 65    
 66    tree[w].left=l;   tree[w].right=r;
 67    ll mid=(l+r)/2;
 68    
 69    if (l==r) {
 70                  tree[w].val=l;
 71                  return;
 72                }
 73 
 74    build(l,mid,2*w);
 75 
 76    build(mid+1,r,2*w+1);
 77 
 78    if (dis[tree[2*w].val]>dis[tree[2*w+1].val]) 
 79        tree[w].val= tree[2*w].val;
 80    else 
 81        tree[w].val= tree[2*w+1].val;
 82 
 83 }
 84 
 85 ll query( ll l , ll r , ll w){
 86 
 87    if (l<=tree[w].left&&tree[w].right<=r) return tree[w].val;
 88 
 89    ll t1=0,t2=0;
 90 
 91    if (l<=tree[2*w].right) t1=query(l,r,2*w);
 92    if (tree[2*w+1].left<=r) t2=query(l,r,2*w+1);
 93    if (dis[t1]>dis[t2]) return t1;
 94    if (dis[t1]==dis[t2]) return min(t1,t2);
 95      else return t2;
 96 }
 97 
 98 
 99 
100 void build2( ll l , ll r , ll w){
101    
102    tree2[w].left=l;   tree2[w].right=r;
103    ll mid=(l+r)/2;
104    
105    if (l==r) {
106                  tree2[w].val=l;
107                  return;
108                }
109 
110    build2(l,mid,2*w);
111 
112    build2(mid+1,r,2*w+1);
113 
114    if (tir[tree2[2*w].val]>tir[tree2[2*w+1].val]) 
115        tree2[w].val= tree2[2*w].val;
116    else 
117        tree2[w].val= tree2[2*w+1].val;
118 
119 }
120 
121 ll query2( ll l , ll r , ll w){
122 
123    if (l<=tree2[w].left&&tree2[w].right<=r) return tree2[w].val;
124 
125    ll t1=0,t2=0;
126    
127    if (l<=tree2[2*w].right) t1=query2(l,r,2*w);
128    if (tree2[2*w+1].left<=r) t2=query2(l,r,2*w+1);
129   
130    if (tir[t1]>tir[t2]) return t1;
131    if (tir[t1]==tir[t2]) return min(t1,t2);
132      else return t2;
133 }
134 
135 void update2( ll x, ll w){
136 
137     if (x==tree2[w].left&&x==tree2[w].right) {
138                               tree2[w].val=0; 
139                               return;
140                           }
141    if (x<=tree2[2*w].right) update2(x,2*w);
142         else  update2(x,2*w+1);
143        
144    if (tir[tree2[2*w].val]>tir[tree2[2*w+1].val]) 
145        tree2[w].val= tree2[2*w].val;
146    else 
147        tree2[w].val= tree2[2*w+1].val;  
148 }
149 void update( ll x, ll w){
150 
151     if (x==tree[w].left&&x==tree[w].right) {
152                               tree[w].val=0; 
153                               return;
154                           }
155    if (x<=tree[2*w].right) update(x,2*w);
156         else  update(x,2*w+1);
157        
158    if (dis[tree[2*w].val]>dis[tree[2*w+1].val]) 
159        tree[w].val= tree[2*w].val;
160    else 
161        tree[w].val= tree[2*w+1].val;  
162 }
163 
164 int main(){
165 
166      init();
167 
168      memcpy(diss,dis,sizeof(dis));
169      for (ll i=1;i<=n;i++)
170          dis[i]=dis[i]*2+tir[i]; 
171      build(1,n,1);
172      build2(1,n,1);
173     
174     ll last=query(1,n,1),php1,php2;
175     ll ans=dis[last];
176     update(last,1);
177     update2(last,1);
178   //  printf("last=%lld ans=%lld
",last,ans);
179     printf("%lld
",ans);
180     for (ll i=2;i<=n;i++)
181     {
182         ap=i;
183         php1=query2(1,last-1,1);
184         if (last+1<=n)php2=query(last+1,n,1); else php2=0;
185      //   printf("%lld %lld 
",dis[php2],last);
186         if (tir[php1]>dis[php2]-diss[last]*2) {
187           ans+=tir[php1];
188          update2(php1,1);update(php1,1);
189             }
190         else {
191           ans+=dis[php2]-diss[last]*2;
192           last=php2;
193           update(php2,1);
194           update2(php2,1);
195         }
196   //   printf("last=%lld ans=%lld
",last,ans);
197     printf("%lld
",ans);
198    }
199    // printf("%lld 
",tir[0]);
200    return 0;
201     
202  }
View Code
原文地址:https://www.cnblogs.com/bobble/p/7153229.html