A
Code:
#include
#define INF 0x3f3f3f3f
using namespace std;
int main(){
int T;
cin >> T;
while( T-- ){
int n , x , y , d;
cin >> n >> x >> y >> d ;
if( y == x ) printf("0\n");
else{
if( abs( y - x ) % d == 0 ){
printf("%d\n",abs( y - x ) / d ) ;
}else{
int res = INF ;
if( ( n - y ) % d == 0 ){
res = ( n - x ) / d + ( ( n - x ) % d != 0 ) ;
res += ( n - y ) / d ;
}
if( ( y - 1 ) % d == 0 ){
x -- ;
int num = x / d + ( x % d != 0 ) ;
num += ( y - 1 ) / d ;
res = min( res , num ) ;
}
if( res < INF ) printf("%d\n",res);
else printf("-1\n");
}
}
}
return 0 ;
}
B
Code:
#include
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 2e5 + 66 ;
int rear[AX] ;
int pre[AX] ;
char s[AX] ;
int main(){
int n ;
scanf("%d%s",&n,s+1);
int tot = 0 ;
pre[0] = 0 ;
rear[n+1] = 0 ;
int res = 0 ;
for( int i = 1 ; i <= n ; i ++ ){ //wei
if( s[i] == 'G' ){
tot ++ ;
pre[i] = pre[i-1] + 1 ;
}else pre[i] = 0 ;
res = max( res , pre[i] ) ;
}
for( int i = n ; i >= 1 ; i -- ){ //tou
if( s[i] == 'G' ){
rear[i] = rear[i+1] + 1 ;
}else rear[i] = 0 ;
}
s[0] = 'S';
s[n+1] = 'S' ;
for( int i = 1 ; i <= n ; i++ ){
if( s[i] == 'S' ){
if( s[i-1] == 'G' && tot > pre[i-1] ){
res = max( res , pre[i-1] + 1 ) ;
}
if( s[i+1] == 'G' && tot > rear[i+1] ){
res = max( res , rear[i+1] + 1 ) ;
}
if( s[i-1] == 'G' && s[i+1] == 'G' ){
if( tot > pre[i-1] + rear[i+1] ){
res = max( res , pre[i-1] + rear[i+1] + 1 ) ;
}else{
res = max( res , pre[i-1] + rear[i+1] ) ;
}
}
}
}
printf("%d\n",res);
return 0 ;
}
C
思路:每门科目所拥有的按从大到小排序,记录前缀和,然后在计算不同长度的总共的最大值,
Code:
#include
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 2e5 + 666 ;
std::vector<int> v[AX];
LL sum[AX] ;
bool cmp( int a , int b ){
return a > b ;
}
int main(){
int n , m ;
scanf("%d%d",&n,&m) ;
int x ;
LL y ;
for( int i = 0 ; i < n ; i++ ){
scanf("%d%I64d",&x,&y);
v[x].push_back(y) ;
}
int len = 0 ;
for( int i = 1 ; i <= m ; i++ ){
sort( v[i].begin() , v[i].end() , cmp ) ;
len = max( len , (int)v[i].size() ) ;
}
for( int i = 1 ; i <= m ; i++ ){
int k = v[i].size() ;
for( int j = 1 ; j < k ; j++ ){
v[i][j] += v[i][j-1] ;
}
}
LL res = 0LL ;
for( int i = 1 ; i <= m ; i ++ ){
for( int j = 0 ; j < v[i].size() ; j++ ){
if( v[i][j] > 0 ){
sum[j+1] += v[i][j] ;
}
}
}
for(int i=1;i<=len;i++){
res=max(sum[i],res);
}
printf("%I64d\n",res);
return 0 ;
}
D
思路:两个度以上的连起来,两头连接一个度的,剩下一度的在分支。
Code:
#include
using namespace std;
const int AX = 5e2 + 6 ;
struct Node{
int id ;
int d ;
bool operator < ( const Node &ch )const{
return d > ch.d ;
}
}a[AX];
std::vector<int> G[AX];
int cnt[AX] ;
int main(){
int n ;
scanf("%d",&n) ;
int tot = 0 ;
for( int i = 1 ; i <= n ; i++ ){
scanf("%d",&a[i].d) ;
cnt[i] = a[i].d ;
if( a[i].d > 1 ) tot ++ ;
a[i].id = i ;
}
sort( a + 1 , a + n + 1 ) ;
stack<int>s;
G[a[1].id].push_back(a[n].id) ;
cnt[a[1].id] -- ;
cnt[a[n].id] -- ;
if( cnt[a[1].id] ) s.push( a[1].id ) ;
int m = 1 ;
for( int i = 2 ; i <= n - 1 ; i++ ){
if( s.size() ){
int x = s.top() ;
G[x].push_back(a[i].id);
m ++ ;
if( --cnt[x] == 0 ){
s.pop() ;
}
if( --cnt[a[i].id] > 0 ){
s.push(a[i].id) ;
}
}else{
return 0*printf("NO\n");
}
}
printf("YES %d\n",min(n-1,tot+1));
printf("%d\n",m);
for( int i = 1 ; i <= n ; i++ ){
for( int j = 0 ; j < G[i].size() ; j++ ){
printf("%d %d\n",i,G[i][j]);
}
}
return 0 ;
}
E
思路:这题思路倒是不难想,看了一个很简单的实现,以后要多用c11特性。
sum[i] 为1-i中c的个数
cnt[i]为 1 - i中x的个数
要求最后最大的c个数,就是找一个区间[l,r]让其中的x都加上c-x,这样,原先该区间的x变为c,原先该区间的c就不是c了。
所以res = max( sum[n] - sum[r] + sum[l-1] + cnt[r] - cnt[l-1] )
上面删除线部分在r一定时都是固定的,
所以我们求max( sum[l-1] - cnt[l-1] )
一路维护这个值就行了。
Code:
#include
using namespace std;
const int AX = 5e5 + 6 ;
int a[AX] ;
int sum[AX] ;
map<int,std::vector<int> >mp;
int cnt[AX] ;
int main(){
int n , c ;
scanf("%d%d",&n,&c) ;
int res = 0 ;
for( int i = 1 ; i <= n ; i++ ){
scanf("%d",&a[i]) ;
if( a[i] == c ) res ++ ;
sum[i] = sum[i-1] + ( a[i] == c ) ;
mp[a[i]].push_back(i) ;
}
for( auto i : mp ){
std::vector<int> tmp = i.second ;
int val = i.first , t = 0 ;
for( const auto &pos : tmp ){
t = max( sum[pos-1] - cnt[val] , t ) ;
cnt[val] ++ ;
res = max( res , sum[n] - sum[pos] + cnt[val] + t ) ;
}
}
printf("%d\n",res);
return 0 ;
}