1203A Circle of Students
题意:给
n
n
n个数,把这
n
n
n个数围成一圈,问能不能从其中一个位置开始沿顺时针或者逆时针方向走都是单调递或者单调递减且两两相差不超过1,(除了1和
n
n
n相差
n
−
1
n-1
n−1)
思路:直接遍历一遍,记录相差1或者相差
n
−
1
n-1
n−1的个数
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <iostream>
#include <queue>
#include <string>
#include <math.h>
typedef long long LL;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define mid(l,r) (( l + r ) / 2)
#define lowbit(x) (( x & ( - x )))
#define lc(root) ((root * 2))
#define rc(root) ((root * 2 + 1))
#define me(array,x) (memset( array , x , sizeof( array ) ) )
const int maxn = 1e5;
int num[maxn];
int main()
{
int q;
scanf("%d",&q);
while(q--){
int n;scanf("%d",&n);
int flag = 0;
scanf("%d",&num[1]);
for(int i=2;i<=n;i++){
scanf("%d",&num[i]);
if(abs(num[i]-num[i-1])==1||abs(num[i]-num[i-1])==n-1){
flag++;
}
}
if(flag==n-1)printf("YES\n");
else printf("NO\n");
}
return 0;
}
1203B Equal Rectangles
题意:给
4
∗
n
4*n
4∗n个木棒,问能不能将这些木棒拼起来使得每个矩形面积一样
思路:先排序,然后再分别从数组的两端取出元素判断即可
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <iostream>
#include <queue>
#include <string>
#include <math.h>
typedef long long LL;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define mid(l,r) (( l + r ) / 2)
#define lowbit(x) (( x & ( - x )))
#define lc(root) ((root * 2))
#define rc(root) ((root * 2 + 1))
#define me(array,x) (memset( array , x , sizeof( array ) ) )
const int maxn = 1e5;
int num[maxn];
int main()
{
int q;
scanf("%d",&q);
while(q--){
int n;scanf("%d",&n);
for(int i=1;i<=n*4;i++)
scanf("%d",&num[i]);
sort(num+1,num+1+4*n);
int flag = 1;
int ans = num[1] * num[4*n];
for(int i = 1 , j = 4*n ; i <= 2*n-1 ; i += 2 , j -= 2){
if((num[i] != num[i+1])||(num[j] != num[j-1])){//相邻的两个数不相同肯定不行
flag=0;
break;
}
if(num[i] * num[j] != ans){
flag=0;
break;
}
}
if(flag)printf("YES\n");
else printf("NO\n");
}
return 0;
}
1203C Common Divisors
题意:给
n
n
n个数,找这
n
n
n个数的公因子个数最多是多少
思路:找到
n
n
n个数的最大公约数,再找最大公约数的因子个数,用 set 记录因子个数
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <iostream>
#include <queue>
#include <string>
#include <math.h>
typedef long long LL;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define mid(l,r) (( l + r ) / 2)
#define lowbit(x) (( x & ( - x )))
#define lc(root) ((root * 2))
#define rc(root) ((root * 2 + 1))
#define me(array,x) (memset( array , x , sizeof( array ) ) )
const int maxn = 4e5+10;
LL num[maxn];
set<LL>s;
int main()
{
int n;
scanf("%d",&n);
scanf("%lld",&num[1]);
LL gcd = num[1];
for(int i = 2 ; i <= n ; i++){
scanf("%lld",&num[i]);
gcd = __gcd(num[i],gcd);
}
for(LL i = 1 ; i * i <= gcd ; i++){
if(gcd % i == 0){
s.insert(i);
s.insert(gcd/i);
}
}
printf("%d\n",s.size());
return 0;
}
1203D1 Remove the Substring (hard version)
1203D2 Remove the Substring (hard version)
题意:给一个字符串
s
s
s,再给一个
s
s
s中的子序列
t
t
t,问从
s
s
s中删除最长子串,使得
t
t
t任然是
s
s
s的子序列。求最长子串的长度
思路:三种情况:子序列
t
t
t的第一个字符在
s
s
s中位置、最后一个字符在
s
s
s中的位置、还有子序列中间的每个空隙在原序列中夹着多少字符,取上述三者最大就行了。对于第三种情况,由于子序列在
s
s
s中的位置可能有多种情况,那么就用两个数组来分别来存子序列每个字符在
s
s
s中的位置,一个数组从
s
s
s的正序开始遍历(简称前缀数组),一个从
s
s
s的逆序开始遍历(简称后缀数组),最后再遍历后缀数组的第
i
i
i个元素减去前缀数组的第
i
−
1
i-1
i−1个元素的最大值就行了。
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <iostream>
#include <queue>
#include <string>
#include <math.h>
typedef long long LL;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define mid(l,r) (( l + r ) / 2)
#define lowbit(x) (( x & ( - x )))
#define lc(root) ((root * 2))
#define rc(root) ((root * 2 + 1))
#define me(array,x) (memset( array , x , sizeof( array ) ) )
const int maxn = 1e6;
int a[maxn],b[maxn];
char s[maxn],t[maxn];
int main()
{
scanf("%s%s",s+1,t+1);
int n = strlen(s+1);
int m = strlen(t+1);
for(int i = 1 , j = 1 ; i <= n ;){
while(s[i] != t[j])
i++;
a[j] = i;
if(j == m)break;
j++;i++;
}
a[m + 1] = n + 1 ; a[0] = 0;
for(int i = n , j = m ; i >= 1 ;){
while(s[i] != t[j])
i--;
b[j] = i;
if(j == 1)break;
j--;i--;
}
b[m + 1] = n + 1 ; b[0] = 0;
int ans1 = a[1] - 1;
for(int i = 1 ; i <= m+1 ; i++)
ans1 = max(b[i] - a[i-1] - 1 , ans1);
printf("%d\n",ans1);
return 0;
}
1203E Boxers
题意:给n个数,每个数可以加一、减一、或者不变,但是每个数必须大于零,问在对一些数操作之后,最多有多少不同的数
思路:先排序,最好的情况就是从最小的数开始每次增加一,所以就从小的开始遍历,用按-1、0、+1的顺序往set里加。看代码,一看就懂。
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <iostream>
#include <queue>
#include <string>
#include <math.h>
typedef long long LL;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define mid(l,r) (( l + r ) / 2)
#define lowbit(x) (( x & ( - x )))
#define lc(root) ((root * 2))
#define rc(root) ((root * 2 + 1))
#define me(array,x) (memset( array , x , sizeof( array ) ) )
const int maxn = 1e6;
int num[maxn];
int main()
{
int n ; scanf("%d",&n);
for(int i = 1 ; i <= n ; i++){
scanf("%d",&num[i]);
}
sort(num+1,num+n+1);
set<int>q;
for(int i = 1 ; i <= n ; i++){
int x = num[i];
if(!q.count(x - 1) && x != 1)
q.insert(x - 1);
else if(!q.count(x))
q.insert(x);
else if(!q.count(x + 1))
q.insert(x + 1);
}
printf("%d\n",q.size());
return 0;
}
1203F1 Complete the Projects (easy version)
题意:小明最初有
m
m
m点活力值,现在有
n
n
n个任务,每个任务有两个参数
a
a
a、
b
b
b分别代表完成该任务需要一个最基础的活力值
a
a
a(小明的活力值必须大于等于
a
a
a才能做这个任务),做完这个任务之后的活力值会增加(或减少)
b
b
b,问小明能否做完所有任务。
思路:对于
b
b
b是正的来说,就按照
a
a
a小的来排序就行了,这样活力值就会一直增加,直到开始做
b
b
b时负的;那么对于
b
b
b是负的来说,需要
a
a
a较大的并且消耗活力值较小的排在前面(也就是
b
b
b大的),所以就按照
a
+
b
a+b
a+b大的排在前面就行了。
{
x
.
a
>
y
.
a
x
.
b
>
y
.
b
\begin{cases} x.a>y.a \\ x.b>y.b \end{cases}
{x.a>y.ax.b>y.b
合并不等式:
x
.
a
+
x
.
b
>
y
.
a
+
y
.
b
x.a+x.b>y.a+y.b
x.a+x.b>y.a+y.b
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <iostream>
#include <queue>
#include <string>
#include <math.h>
typedef long long ll;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define mid(l,r) (( l + r ) / 2)
#define lowbit(x) (( x & ( - x )))
#define lc(root) ((root * 2))
#define rc(root) ((root * 2 + 1))
#define me(array,x) (memset( array , x , sizeof( array ) ) )
const int maxn = 1e3;
struct node {int a,b;}s[maxn];
int cmp (node a,node b){
if(a.b >= 0 && b.b >= 0)
return a.a < b.a;
else if(a.b < 0 && b.b < 0)
return a.a + a.b > b.a + b.b;
else
return a.b > b.b;//对于b有一个是正的另一个是负的来说,就把正的排在前面
}
int main()
{
int n,r;
scanf("%d%d",&n,&r);
for(int i = 1 ; i <= n ; i++){
scanf("%d%d",&s[i].a,&s[i].b);
}
sort(s+1,s+1+n,cmp);
int ans = r;
int flag = 0;
for(int i = 1 ; i <= n ; i++){
if(s[i].a > ans){
flag = 1;
break;
}
ans += s[i].b;
}
if(flag || ans < 0)printf("NO\n");
else printf("YES\n");
return 0;
}
1203F2 Complete the Projects (easy version)
题意:和F1差不多,但问的是最多能做几个任务
思路:不会