SMU ACM 2021划水赛
A P6284 [COCI2016-2017#1] Tarifa
水题
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
int n , a[N] , b[N] , cnt1 , cnt2;
set<int> c;
inline int read()
{
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x * f;
}
int main()
{
int x = read() , n = read() , sum = 0;
for( int i = 1 , y ; i <= n ; i ++ )
y = read() , sum += y;
cout << x * (n+1) - sum << endl;
return 0;
}
B P6320 [COCI2006-2007#4] SIBICE
最长边是对角线,小技巧不用开方
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
int n , a[N] , b[N] , cnt1 , cnt2;
set<int> c;
inline int read()
{
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x * f;
}
int main()
{
int n = read() , w = read() , h = read() , l = w * w + h * h ;
for( int i = 1 , x ; i <= n ; i ++ )
{
x = read();
if( x * x <= l ) printf("DA\n");
else printf("NE\n");
}
return 0;
}
C P6321 [COCI2006-2007#4] SKENER
这个问题分开了考虑,如果每一行重复\(r\)次
for( int i = 1 ; i <= ; i ++ )
for( int k = 1 ; k <= r ; k ++ )
{
for( int j = 1 ; j <= m ; j ++ )
cout << g[i][j];
cout << endl;
}
如果每一列重复\(c\)次
for( int i = 1 ; i <= ; i ++ )
{
for( int j = 1 ; j <= ; j ++ )
for( int k = 1 ; k <= c ; k ++ )
cout << g[i][j];
cout << endl;
}
把两种情况和起来就好了
#include<bits/stdc++.h>
using namespace std;
int n , m , r , c;
string s;
int main()
{
cin >> n >> m >> r >> c;
for( int i = 1 ; i <= n ; i ++ )
{
cin >> s;
for( int k = 1 ; k <= r ; k ++ ) {
for (auto it: s)
for (int j = 1; j <= c; j++)
cout << it;
cout << endl;
}
}
return 0;
}
D P1413 坚果保龄球
这道题可以把所有的僵尸认为是静止不动的,然后每个僵尸的坐标就是\((p,t)\),然后问最少需要多少个\(1\times60\)的矩形可以覆盖所有的僵尸
每一行都是相互独立的,对于每一行贪心的覆盖就好了
#include<bits/stdc++.h>
#define l first
#define r second
using namespace std;
int n , cnt ;
vector<int> s[8];
inline int read()
{
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x * f;
}
int main()
{
n = read();
for( int p , t ; n ; n -- )
{
p = read() , t = read();
s[p].push_back(t);
}
for( int i = 1 , t = -1 ; i <= 6 ; t = -1 , i ++ )
{
sort( s[i].begin() , s[i].end() );
for( int j = 0 ; j < s[i].size() ; j ++ )
{
if( t == -1 ) t = s[i][j];
else if( t + 60 - 1 >= s[i][j] ) continue;
else cnt ++ , t = s[i][j];
}
cnt += (t > 0 );
}
cout << cnt << endl;
return 0;
}
P1901 发射站
最近的且比他高,要先满足比他高,正常的逻辑应该是暴力找就好但是会TLE
向左发射能量和向右类似,我们先处理向右的
首先从左侧开始枚举,用一个队列维护之前的递减序列,这个序列均没有向右发射过能量,对于当前的能量站只要比队列头高,就是离队头最近切比他高的,就会收到对头的能量,然后就要弹出对头,重复这个过程直到比队头低或者队空,然后当前的能量站入队
对于向左发射过程基本相同倒着做一遍就好,最后在扫描一遍就好了,因为每一个只会入队两次出队两次所以
#include<bits/stdc++.h>
#define l first
#define r second
using namespace std;
const int N = 1e6+5;
int n , h[N] , v[N] , val[N] , res = 0;
stack<int> s;
inline int read()
{
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x * f;
}
int main()
{
n = read();
for( int i = 1 ; i <= n ; i ++ )
h[i] = read() , v[i] = read();
for( int i = 1 ; i <= n ; i ++ )
{
if( s.empty() ){
s.push( i );
continue;
}
while( s.size() && h[s.top()] < h[i] )
val[i] += v[s.top()] , s.pop();
s.push(i);
}
while( s.size() ) s.pop();
for( int i = n ; i >= 1 ; i -- )
{
if( s.empty() ){
s.push( i );
continue;
}
while( s.size() && h[s.top()] < h[i] )
val[i] += v[s.top()] , s.pop();
s.push(i);
}
for( int i = 1 ; i <= n ; i ++ )
res = max( res , val[i] );
cout << res << endl;
return 0;
}