Codeforces Round #576 (Div. 2)A-City Day(模拟)
题干:给你n个数,同时给你一个x和一个y,问这n个数中哪个数的前面有x个数比他大并且这个数的后面还有y个数比他小,如果都不符合条件则输出n这个值。
解题思路:
按题意模拟即可,注意都不符合条件时的特判
#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define mm(a,n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
int a[ 1209000 ] ;
signed main ( )
{
int n, x, k;
cin>> n>> x>> k;
for ( int i= 0 ; i< n; i++ )
{
scanf ( "%lld" , & a[ i] ) ;
}
for ( int i= 0 ; i< n; i++ )
{
int l= 0 , r= 0 ;
int flag= 0 , flag1= 0 ;
for ( int j= i- 1 ; j>= - 1 ; j-- )
{ if ( j== - 1 )
{
flag= 1 ; break ;
}
if ( l== x)
break ;
if ( a[ j] > a[ i] )
{
l++ ;
}
else {
break ;
}
}
for ( int j= i+ 1 ; j<= n; j++ )
{ if ( j== n)
{
flag1= 1 ; break ;
}
if ( r== k)
break ;
if ( a[ j] > a[ i] )
{
r++ ;
}
else
break ;
}
if ( ( flag== 1 && flag1== 1 ) || ( l== x&& r== k) || ( flag== 1 && r== k) || ( l== x&& flag1== 1 ) )
{ printf ( "%lld\n" , i+ 1 ) ; break ;
}
if ( i== n- 1 )
printf ( "%lld\n" , i+ 1 ) ;
}
}
Codeforces Round #576 (Div. 2)B. Water Lily(小学计算题)
题干:给你H L,问点A到水面的距离。
解题思路:小学计算题,用笔算一下即可,注意能化简尽量化简。输出时用printf,用cout会错,因为精度不够。
#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define mm(a,n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
int a[ 1209000 ] ;
signed main ( )
{
double l, h;
cin>> h>> l;
printf ( "%.8f\n" , double ( l* l) / 2 / h- double ( h) / 2 ) ;
}
Codeforces Round #576 (Div. 2)C. MP3(思维)
题干:给定n和I,以此来确定一个数k=8*i/n;保证输入的数中只有k种不同的数,你可以选定一个1到n中一个连续的区间,使得不在这个区间内的数变成这个区间内的数以符合条件。样例解释中有说明(表达不好请见谅)
解题思路:输入时用map储存每个数的个数,同时将所有不同的数存到a数组中(即a数组中所有的数都是不同的)。后将a数组排序。用b数组和c数组分别存a数组中的数的每个数的个数的前缀和和后缀和。最后通过一个for循环遍历即可求解(确定你要删除的数的个数,每次取前缀数组的b[i]的值和后缀数组c[删除数的个数-i]的值)
#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define mm(a,n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
int a[ 1209000 ] ;
int b[ 1200000 ] ;
int c[ 1200000 ] ;
map< int , int > mp1;
signed main ( )
{
int n, k;
scanf ( "%lld %lld" , & n, & k) ;
int ans= 1 ;
int m;
for ( int i= 1 ; i<= n; i++ )
{
scanf ( "%lld" , & m) ;
if ( mp1[ m] == 0 )
{
mp1[ m] ++ ;
a[ ans++ ] = m;
}
else
{
mp1[ m] ++ ;
}
}
sort ( a+ 1 , a+ ans) ;
int sum= k* 8 / n;
if ( sum> 32 )
printf ( "0\n" ) ;
else
{ ans= ans- 1 ;
int qwer= 0 ; int shuliang= 0 ;
int sum1= pow ( 2 , sum) ;
if ( ans<= pow ( 2 , sum) )
printf ( "0\n" ) ;
else
{
for ( int i= 1 ; i<= ans; i++ )
{
if ( i== 1 )
b[ i] = mp1[ a[ i] ] ;
else
b[ i] = b[ i- 1 ] + mp1[ a[ i] ] ;
}
for ( int i= ans, j= 1 ; i>= 1 ; i-- , j++ )
{
if ( i== ans& j== 0 )
c[ j] = mp1[ a[ i] ] ;
else
c[ j] = c[ j- 1 ] + mp1[ a[ i] ] ;
}
int minn= 999999 ;
for ( int i= 0 ; i< ans- sum1; i++ )
{
minn= min ( minn, b[ i] + c[ ans- sum1- i] ) ;
}
printf ( "%lld\n" , minn) ;
}
}
return 0 ;
}
Codeforces Round #576 (Div. 2)D. Welfare State(巧妙思维)
题干:给你n个数,同时给你q次操作,当操作为2时,输入一个数,将这n个数中所有小于这个数的数变成这个数。当操作为1时,输入两个数分别为位置和修改的值,做单点修改。
解题思路:我们用一个数组保存所有单点修改后的最终值和再用一个数组记录每次单点修改是第几次进行修改。随后再用数组d保存每次区间修改的值。做法为将d数组从后向前遍历,每次取最大值作为最终值(思考一下为什么这么做),然后一个for循环输出时每次取这个数单点修改的最终值与那次修改之后的d数组中的数取最大值即为最终要输出的值。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define N 200010
int a[ N] , t[ N] , d[ N] ;
int main ( ) {
int i, n, q;
cin>> n;
for ( i= 1 ; i<= n; i++ ) cin>> a[ i] ;
cin>> q;
for ( i= 1 ; i<= q; i++ ) {
int opt, p, x;
cin>> opt;
if ( opt== 1 ) {
cin>> p>> x;
a[ p] = x; t[ p] = i;
} else { cin>> x; d[ i] = x; }
}
for ( i= q- 1 ; i>= 0 ; i-- ) d[ i] = max ( d[ i] , d[ i+ 1 ] ) ;
for ( i= 1 ; i<= n; i++ ) printf ( "%d " , max ( a[ i] , d[ t[ i] ] ) ) ;
return 0 ;
}