A
原题链接
题意:T组数组,每组一个n,现在让你构造一个长度为n的数组,要求数组满足对所有的1<=x,y,z<=n,ax+ay ≠ az (a不一定不同)
题解:因为是spj,我们只需要构造出一个长度为n,元素全为1的数组就行了
#include < bits / stdc ++. h >
using namespace std ;
int n , k ;
int main () {
cin >> n ;
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "% d" , & k );
for ( int j = 1 ; j <= k ; j ++) {
if ( j ! = k ) printf ( "1" );
else printf ( "1 \ n" );
}
}
return 0 ;
}
B
原题链接
题意:T组数据,每组一个n,现在需要你找到一个a和一个b,使得 a + b = n并且LCM(a,b) 最小
题解:
考虑n的奇偶性:
1.如果n是偶数,显然我们可以构造出a=b=n/2使得LCM最小
2.如果n是奇数,因为n的大小最多是1e9,可以考虑从3往上找,找到第一个n的因子k,则a=n/k,b=n-a
如果找不到,说明n是个质数,则a=1,b=n-1
复杂度: O ( n ) O(\sqrt[]{n}) O(n)
#include <bits/stdc++.h>
using namespace std;
int n,T;
int main(){
cin>>T;
while(T--){
scanf("%d",&n);
if(n % 2==0){
printf("%d %d\n",n/2,n/2);
continue;
}
int flag=0;
for (int i=3;i<=sqrt(n);i++){
if(n % i == 0){
flag = 1;
printf("%d %d\n",n/i,n-(n/i));
break;
}
}
if(!flag) printf("1 %d\n",n-1);
}
return 0;
}
C
原题链接
题意:T组数据,每组一个n,之后是一个长度为n的数组a,数组a是一个n的排列。对于每组数据,现在你可以对数组做如下操作:把[L,R]这一个连续区间的数改变位置(且要保证改变后区间中的每个数不能在原来的位置上),如:[1,2,3]可以变化为[3,1,2],但不能是[3,2,1]。现在问最少需要几次这样的区间变化操作使得数组a有序
题解:先看几个特例:
(设至少需要k次操作)
1.当数组开始有序,则k=0
2.当数组是一个完全乱序(即每个a[i]都不在i位置上),则我们只需要1次对于区间[1,n]的操作就可以使得有序
3.不是完全乱序。因为每次操作针对的是一个连续的区间,所以我们可以先将问题简化,设定两个指针l,r,初始时l=1,r=n,如果从左到右a[i] = i,则l++,如果从右到左a[i] = i,则r–,则我们现在需要操作的区间就是[l,r]这个区间了。
然后再观察[l,r]这个区间
由2我们可以知道,如果[l,r]这个区间完全乱序,则k=1,如果[l,r]这个区间不是完全乱序,打个比方:1,2,5,4,3,6,7,[5,4,3]这个区间,我们只需要先操作一次变为[4,5,3],再操作一次变为[3,4,5]就可以了,则k=2。
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 2e5 + 10 ;
int n , T ;
int a [ maxn ], b [ maxn ];
int main () {
cin >> T ;
while ( T --) {
scanf ( "%d" , &n );
int cnt = 0 ;
for ( int i = 1 ; i <= n ; i ++) {
scanf ( "%d" , & a [ i ]);
if ( a [ i ] == i ) cnt ++;
}
if ( cnt == n ) {
puts ( "0" ); continue ;
}
if ( cnt == 0 ) {
puts ( "1" ); continue ;
}
int l = 1 , r = n ;
while ( a [ l ] == l ) l ++;
while ( a [ r ] == r ) r --;
cnt = 0 ;
for ( int i = l ; i <= r ; i ++) {
if ( a [ i ] == i ) cnt ++;
}
if ( cnt != 0 ) puts("2");
else puts ("1");
}
return 0 ;
}
* /
D
原题链接
题意:给你一个奇数长度为n的循环数组(首位相连接,a[1]与a[n]相邻),现在进行若干次操作,每次选数组中任意一个数,然后用它相邻两个数之和替换掉它,问最后剩下的这个数最大是多少
题解: