这次的群赛AK的不少,7题的也很多啊。。Orrrrrrrz。。。。
暂时只写出7题。。。
A:1196
模拟。。
/*
* this code is made by poursoul
* Problem: 1196
* Verdict: Accepted
* Submission Date: 2014-09-06 19:12:44
* Time: 0MS
* Memory: 1088KB
*/
#include <map>
#include <cmath>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
typedef long long LL ;
int n , cur , d ;
void solve () {
if ( cur == 1 ) printf ( "[<<]" ) ;
else printf ( "(<<)" ) ;
if ( cur - d <= 1 ) {
REP ( i , 1 , cur ) printf ( "(%d)" , i ) ;
} else {
printf ( "[...]" ) ;
REP ( i , cur - d , cur ) printf ( "(%d)" , i ) ;
}
printf ( "[%d]" , cur ) ;
if ( cur + d >= n ) {
FOR ( i , cur + 1 , n ) printf ( "(%d)" , i ) ;
} else {
FOR ( i , cur + 1 , cur + d ) printf ( "(%d)" , i ) ;
printf ( "[...]" ) ;
}
if ( cur == n ) printf ( "[>>]\n" ) ;
else printf ( "(>>)\n" ) ;
}
int main () {
int cas = 0 ;
while ( ~scanf ( "%d%d%d" , &n , &cur , &d ) ) {
printf ( "Case #%d: " , ++ cas ) ;
solve () ;
}
return 0 ;
}
C:1198
要求每个点到起点的路径长度加上到终点的路径长度里最长的最短。
那么可以对起点以及终点分别求一次最短路,路径相加取最长即可。
注意从起点到终点的不用相加。
/*
* this code is made by poursoul
* Problem: 1198
* Verdict: Accepted
* Submission Date: 2014-09-07 10:02:52
* Time: 304MS
* Memory: 4232KB
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
typedef long long LL ;
const int MAXN = 1005 ;
const int MAXE = 200005 ;
const int INF = 0x3f3f3f3f ;
struct Edge {
int v , c ;
Edge* next ;
} E[MAXE] , *H[MAXN] , *cur ;
int Q[MAXN] , head , tail ;
bool vis[MAXN] ;
int d[2][MAXN] ;
int n , m , s , t ;
void clear () {
cur = E ;
CLR ( H , 0 ) ;
}
void addedge ( int u , int v , int c ) {
cur -> v = v ;
cur -> c = c ;
cur -> next = H[u] ;
H[u] = cur ++ ;
}
void spfa ( bool o , int s ) {
CLR ( vis , 0 ) ;
CLR ( d[o] , INF ) ;
head = tail = 0 ;
Q[tail ++] = s ;
d[o][s] = 0 ;
while ( head != tail ) {
int u = Q[head ++] ;
if ( head == MAXN ) head = 0 ;
vis[u] = 0 ;
travel ( e , H , u ) {
int v = e -> v ;
if ( d[o][v] > d[o][u] + e -> c ) {
d[o][v] = d[o][u] + e -> c ;
if ( !vis[v] ) {
if ( d[o][v] < d[o][Q[head]] ) {
if ( head == 0 ) head = MAXN ;
Q[-- head] = v ;
} else {
Q[tail ++] = v ;
if ( tail == MAXN ) tail = 0 ;
}
vis[v] = 1 ;
}
}
}
}
}
void solve () {
int u , v , c ;
clear () ;
scanf ( "%d%d" , &n , &m ) ;
REP ( i , 0 , m ) {
scanf ( "%d%d%d" , &u , &v , &c ) ;
addedge ( u , v , c ) ;
addedge ( v , u , c ) ;
}
scanf ( "%d%d" , &s , &t ) ;
spfa ( 0 , s ) ;
spfa ( 1 , t ) ;
int ans = 0 ;
REP ( i , 0 , n ) {
//printf ( "s-%d:%d t-%d:%d\n" , i , d[0][i] , i , d[1][i] ) ;
if ( i == s || i == t ) ans = max ( ans , d[0][i] ) ;
else ans = max ( ans , d[0][i] + d[1][i] ) ;
}
printf ( "%d\n" , ans ) ;
}
int main () {
int T , cas = 0 ;
scanf ( "%d" , &T ) ;
while ( T -- ) {
printf ( "Case #%d: " , ++ cas ) ;
solve () ;
}
return 0 ;
}
D:1199
对人以及装备按升序排序,因为排在前面能拿的装备排在后面的一定能拿,令f[ i ]为排在第i位的人能拿的装备数,则ans = f[ 1 ] * ( f[ 2 ] - 1 ) * ( f[ 3 ] - 2 ) * ... * ( f[ n ] - ( n - 1 ) )
/*
* this code is made by poursoul
* Problem: 1199
* Verdict: Accepted
* Submission Date: 2014-09-07 10:19:39
* Time: 508MS
* Memory: 1868KB
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
typedef long long LL ;
const int MAXN = 100005 ;
const int mod = 1e9 + 7 ;
int a[MAXN] ;
int b[MAXN] ;
int n ;
void solve () {
scanf ( "%d" , &n ) ;
FOR ( i , 1 , n ) scanf ( "%d" , &a[i] ) ;
FOR ( i , 1 , n ) scanf ( "%d" , &b[i] ) ;
sort ( a + 1 , a + n + 1 ) ;
sort ( b + 1 , b + n + 1 ) ;
int j = 0 , cnt = 0 ;
LL ans = 1 ;
FOR ( i , 1 , n ) {
while ( j < n && a[j + 1] <= b[i] ) ++ j ;
ans = ( ans * ( j - i + 1 ) ) % mod ;
}
printf ( "%d\n" , ans ) ;
}
int main () {
int T , cas = 0 ;
scanf ( "%d" , &T ) ;
while ( T -- ) {
printf ( "Case #%d: " , ++ cas ) ;
solve () ;
}
return 0 ;
}
G:1202
直接字符串读进来判断就好了。。
/*
* this code is made by poursoul
* Problem: 1202
* Verdict: Accepted
* Submission Date: 2014-09-06 19:21:16
* Time: 0MS
* Memory: 1088KB
*/
#include <map>
#include <cmath>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
typedef long long LL ;
const int MAXN = 33 ;
char s[MAXN] ;
void solve () {
if ( s[0] == '-' ) {
int len = strlen ( s ) - 1 ;
REP ( i , 0 , len ) s[i] = s[i + 1] ;
if ( len < 5 ) printf ( "short\n" ) ;
else if ( len == 5 ) {
int flag = strcmp ( s , "32768" ) ;
if ( flag <= 0 ) printf ( "short\n" ) ;
else printf ( "int\n" ) ;
}
else if ( len < 10 ) printf ( "int\n" ) ;
else if ( len == 10 ) {
int flag = strcmp ( s , "2147483648" ) ;
if ( flag <= 0 ) printf ( "int\n" ) ;
else printf ( "long long\n" ) ;
}
else if ( len < 19 ) printf ( "long long\n" ) ;
else if ( len == 19 ) {
int flag = strcmp ( s , "9223372036854775808" ) ;
if ( flag <= 0 ) printf ( "long long\n" ) ;
else printf ( "It is too big!\n" ) ;
}
else printf ( "It is too big!\n" ) ;
} else {
int len = strlen ( s ) ;
if ( len < 5 ) printf ( "short\n" ) ;
else if ( len == 5 ) {
int flag = strcmp ( s , "32767" ) ;
if ( flag <= 0 ) printf ( "short\n" ) ;
else printf ( "int\n" ) ;
}
else if ( len < 10 ) printf ( "int\n" ) ;
else if ( len == 10 ) {
int flag = strcmp ( s , "2147483647" ) ;
if ( flag <= 0 ) printf ( "int\n" ) ;
else printf ( "long long\n" ) ;
}
else if ( len < 19 ) printf ( "long long\n" ) ;
else if ( len == 19 ) {
int flag = strcmp ( s , "9223372036854775807" ) ;
if ( flag <= 0 ) printf ( "long long\n" ) ;
else printf ( "It is too big!\n" ) ;
}
else printf ( "It is too big!\n" ) ;
}
}
int main () {
while ( ~scanf ( "%s" , s ) ) solve () ;
return 0 ;
}
H:1203
不忍吐嘈我这傻逼了。。。高中白学了T U T
首先给底边AB一个值,然后求出了AC、BC、AD、DC、BE、EC、AE。
白痴的事来了!我竟然逗比到用海伦公式来求边DE!通过化简(a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c)/16 = 0.5*CD*DE*sin(ACB)来求。。。。简直无语了。。。明明用余弦定理可以很轻松的。。。
还是不多说了。。智商不能暴露的太多。。
/*
* this code is made by poursoul
* Problem: 1203
* Verdict: Accepted
* Submission Date: 2014-09-07 11:23:05
* Time: 0MS
* Memory: 1276KB
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
const double pi = acos ( -1.0 ) ;
int a , b , c , d ;
double rd ( int x ) {
return x * pi / 180.0 ;
}
void solve () {
int A = a + b ;
int B = c + d ;
int C = 180 - A - B ;
int ADB = 180 - A - c ;
int AEB = 180 - b - B ;
if ( !a || !c ) printf ( "%.2f\n" , 0.0 ) ;
else if ( !b ) printf ( "%.2f\n" , 0.0 + c ) ;
else if ( !d ) printf ( "%.2f\n" , 0.0 + b + c ) ;
else {
double AB = 100.0 ;
double AC = AB / sin ( rd ( C ) ) * sin ( rd ( B ) ) ;
double BC = AB / sin ( rd ( C ) ) * sin ( rd ( A ) ) ;
double AD = AB / sin ( rd ( ADB ) ) * sin ( rd ( c ) ) ;
double BE = AB / sin ( rd ( AEB ) ) * sin ( rd ( b ) ) ;
double AE = AB / sin ( rd ( AEB ) ) * sin ( rd ( B ) ) ;
double CD = AC - AD ;
double CE = BC - BE ;
double S_CDE = 0.5 * CD * CE * sin ( rd ( C ) ) ;//S = 0.5absin(C)
//求根公式
double _b = - 2.0 * ( CD * CD + CE * CE ) ;
double ac = 16.0 * S_CDE * S_CDE + pow ( CE * CE - CD * CD , 2.0 ) ;
double x1 = 0.5 * ( -_b - sqrt ( _b * _b - 4.0 * ac ) ) ;
double x2 = 0.5 * ( -_b + sqrt ( _b * _b - 4.0 * ac ) ) ;
double DE = sqrt ( ( C <= 90 ? x1 : x2 ) ) ;
double cos_AED = ( AE * AE + DE * DE - AD * AD ) / ( 2 * AE * DE ) ;
double AED = acos ( cos_AED ) / pi * 180.0 ;
printf ( "%.2f\n" , AED ) ;
}
}
int main () {
while ( ~scanf ( "%d%d%d%d" , &a , &b , &c , &d ) ) solve () ;
return 0 ;
}
I:1204
用下gcd就行了,注意可能为负数即可。
/*
* this code is made by poursoul
* Problem: 1204
* Verdict: Accepted
* Submission Date: 2014-09-07 09:16:14
* Time: 20MS
* Memory: 1088KB
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
typedef long long LL ;
int n ;
int gcd ( int a , int b ) {
return a == 0 ? b : gcd ( b % a , a ) ;
}
void solve () {
int x , y ;
REP ( i , 0 , n ) {
scanf ( "%d%d" , &x , &y ) ;
++ y ;
bool flag = 0 ;
if ( x < 0 ) flag = 1 , x = -x ;
int tmp = gcd ( x , y ) ;
if ( flag ) x = -x ;
printf ( "%d" , x / tmp ) ;
if ( y != tmp ) printf ( "/%d" , y / tmp ) ;
printf ( " " ) ;
printf ( "%d" , y ) ;
if ( i < n - 1 ) printf ( " " ) ;
else printf ( "\n" ) ;
}
}
int main () {
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}
J:1205
这题我开了一个disappear[ ]数组记录这个点是否被淹没,如果块[ i ]被淹没则disappear[ i ] = 1 , 否则disappear[ i ] = 0。首先将所有块按照高度从低到高排个序,然后按照时间顺序依次访问小于等于当前时间的高度的块,将该块标记为被淹没(disappear[] = 1),然后看他的左边和右边是否有被淹没的块,如果左右都没有被淹没,则肯定这个块被淹没以后,一个块分成了两个块,计数+1。如果左边和右边都被淹没,则这个块也被淹没,则少了一个块,计数-1。
/*
* this code is made by poursoul
* Problem: 1205
* Verdict: Accepted
* Submission Date: 2014-09-07 09:32:53
* Time: 1636MS
* Memory: 9876KB
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
typedef long long LL ;
const int MAXN = 1000005 ;
struct Block {
int h ;
int idx ;
bool operator < ( const Block& a ) const {
return h < a.h ;
}
} b[MAXN] ;
bool disappear[MAXN] ;
int n , m ;
void solve () {
int s ;
scanf ( "%d%d" , &n , &m ) ;
FOR ( i , 1 , n ) {
scanf ( "%d" , &b[i].h ) ;
b[i].idx = i ;
disappear[i] = 0 ;
}
disappear[0] = disappear[n + 1] = 1 ;
sort ( b + 1 , b + n + 1 ) ;
int now = 1 ;
int cnt = 1 ;
while ( m -- ) {
scanf ( "%d" , &s ) ;
while ( now <= n && b[now].h <= s ) {
int idx = b[now].idx ;
disappear[idx] = 1 ;
if ( !disappear[idx - 1] && !disappear[idx + 1] ) ++ cnt ;
else if ( disappear[idx - 1] && disappear[idx + 1] ) -- cnt ;
now ++ ;
}
printf ( "%d%c" , cnt , m ? ' ' : '\n' ) ;
}
}
int main () {
int T , cas = 0 ;
scanf ( "%d" , &T ) ;
while ( T -- ) {
printf ( "Case #%d: " , ++ cas ) ;
solve () ;
}
return 0 ;
}