题目链接:https://codeforces.com/problemset/problem/1203/E
题意:给定n个数字,每个数字可以进行一次+1或是-1的变换(也可以不变),问通过对部分数字适当变换后n个数中有多少个互不相同的数。
依然是弱鸡补题ing。这道题只要贪心就行了,贪心要注意一点就是在储存完每个值的个数后不要直接给已有的值打标记。为什么呢?为了方便后面进行移动:考虑到存在的一些特殊情况,比如
数字:1 2 3 4 5 6 7
个数:2 1 1 0 1 1 2
对于这个例子,如果我们将原来的2、3整体+1变为3、4,那就可以把4这个空补上,同时使一个1加上1,这段数列中就有7个互不相同的数,但如果一开始就打好标记,就意味着我们无法做出这种移动了。而这种移动的实现方式就是贪心。
具体实现方式就是另建一个vis数组来打标记,从小到大或者从大到小遍历都可以,只要记住哪一边开始就贪心地往哪一边靠,比如从1到150000的话,每个值先看比它小1的有没有vis,已经vis了的话再来标记自己这个值的位置。最后标记完统计一遍输出就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<set> 4 #include<stdio.h> 5 #include<string.h> 6 #include<math.h> 7 #include<vector> 8 #include<stdlib.h> 9 #include<queue> 10 #include<algorithm> 11 #include<map> 12 #include<stack> 13 using namespace std; 14 int n; 15 int a[150010]; 16 int vis[150010]; 17 int main() 18 { 19 scanf("%d",&n); 20 int k; 21 int s=0; 22 for(int i=0;i<n;i++) 23 { 24 scanf("%d",&k); 25 a[k]++; 26 } 27 for(int i=1;i<=150000;i++) 28 { 29 if(a[i]) 30 { 31 for(int j=i-1;j<=i+1;j++) 32 { 33 if(a[i]&&j>0&&!vis[j]) 34 { 35 vis[j]=1; 36 a[i]--; 37 } 38 } 39 } 40 } 41 for(int i=1;i<=150001;i++) 42 { 43 if(vis[i]>0) 44 { 45 s++; 46 } 47 } 48 printf("%d ",s); 49 return 0; 50 }