https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=574
UVA Regionals 2012 :: North America - Greater NY
HDU 上题号是4484 - 4492
A,水题
int ans ;
void dfs(int now){
if(now == 1)return ;
ans = max(ans , now) ;
if(now & 1)dfs(now * 3 + 1) ;
else dfs(now >> 1) ;
}
int main() {
int T ;
cin >> T ;
while(T -- ){
int n , fk ;scanf("%d%d",&n , &fk) ;
ans = fk ;
dfs(fk) ;
printf("%d %d\n",n , ans) ;
}
return 0 ;
}
B,水题,不过题目貌似判不了了
char fk[11111111] ;
int main() {
int T ;
cin >> T ;
while( T -- ){
int n , MOD ;
cin >> n >> MOD ;
MOD -- ;
scanf("%s",fk) ;
int l = strlen(fk) ;
int sum = 0 ;
for (int i = 0 ; i < l ; i ++ ){
sum += fk[i] - '0' ;
}
cout << n << " " << sum % MOD << endl;
}
return 0 ;
}
C,水题,给出三角形的周长,求三角形的个数,如果三边都不等的三角形,计数+2.
int main() {
int T ;
cin >> T ;
while(T -- ){
int n , fk ;
scanf("%d%d",&n,&fk) ;
int maxl = fk / 2 ;
int sum = 0 ;
for (int i = maxl ; i >= 1 ; i -- ){//最长边
for (int j = i ; j >= 1 ; j -- ){//次长边
int now = fk - i - j ;
if(now <= 0)continue ;
if(now > j)break ;
if(now > 0 && i >= now && j >= now){
if(j + now > i && (i != j && i != now && j != now)){
sum += 2 ;
}
else if(j + now > i)sum ++ ;
}
}
}
printf("%d %d\n",n , sum) ;
}
return 0 ;
}
D。概率DP,题意是求出在最右端的期望 ,就是在最右端的各点的概率*该点的值。
我是这么理解的,求出每点的概率,然后乘上该点的位置就是他的期望,最后求和即可。
dp[i][j]表示走了i步,在j点的概率。
那么dp[i][j] = dp[i - 1][j - 1] * p1 + dp[i - 1][j + 1] * p2 + dp[i - 1][j] * (1 - p1 - p2) 。
最后求出dp[m][i] * i 的总和就是期望。
E。模拟找规律打表。
struct kdq {
ll x , y ;
kdq(){}
kdq(ll _x , ll _y) : x(_x) ,y(_y){}
} a[444][444] ;
ll gcd(ll a ,ll b) {
if(b == 0)return a ;
return gcd(b , a % b) ;
}
int main() {
int T ;
a[0][1].x = 1 ,a[0][1].y = 1 ;
for (int i = 1 ; i <= 400 ; i ++ ) {
for (int j = 2 ; j <= i + 1 ; j ++ ) {
ll a1 = 0 ;
ll a2 = 0 ;
if(a[i - 1][j - 1].x == 0 || a[i - 1][j - 1].y == 0){
a[i][j] = kdq(0 , 1) ;
continue ;
}
if(a[i - 1][j - 1].x != 0 && a[i - 1][j - 1].y != 0) {
a1 = a[i - 1][j - 1].x * i ;
a2 = a[i - 1][j - 1].y * j ;
int flag = 1 ;
if(a1 < 0){
a1 = -a1 ;
flag = -1 ;
}
ll c = gcd(a1 , a2) ;
if(c != 0) {
a1 /= c ;
a2 /= c ;
}
a[i][j] = kdq(a1 * flag , a2) ;
}
}
kdq now = kdq(0 ,1) ;
for (int j = 2 ; j <= i + 1 ; j ++ ) {
if(a[i][j].x == 0 || a[i][j].y == 0)continue ;
ll c = gcd(now.y , a[i][j].y) ;
ll cc = now.y / c * a[i][j].y ;
now = kdq(now.x * (cc / now.y) + a[i][j].x * (cc / a[i][j].y) , cc) ;
}
now.x = now.y - now.x ;
// cout << now.x << " " << now.y << endl;
// getchar() ;
a[i][1] = now ;
if(a[i][1].x == 0 || a[i][1].y == 0) {
a[i][1] = kdq( 0 , 1 ) ;
}
else {
ll x = a[i][1].x ;
ll y = a[i][1].y ;
int flag = 1 ;
if(x < 0){
x = -x ;
flag = -1 ;
}
ll c = gcd(x , y) ;
a[i][1] = kdq(x * flag / c , y / c) ;
}
}
cin >> T ;
while( T -- ) {
int n , fk1 , fk2 ;
cin >> n >> fk1 >> fk2 ;
cout << n << " " ;
if(a[fk1][fk2].x < 0 || a[fk1][fk2].y < 0) {
putchar('-') ;
}
if(a[fk1][fk2].x == 0 || a[fk1][fk2].y == 0) {
puts("0") ;
} else {
if(a[fk1][fk2].y == 1) {
printf("%lld\n",abs(a[fk1][fk2].x)) ;
} else {
printf("%lld/%lld\n",abs(a[fk1][fk2].x) ,abs(a[fk1][fk2].y)) ;
}
}
}
return 0 ;
}
F,正解是组合数学+DP。
可以状压打表。
注意i = 1的时候答案为1.
ll dp[1 << 20][22][2] ;
ll ans[22] ;
ll get(int n){
mem(dp ,0) ;
for (int i = 0 ; i < n ; i ++ ){
dp[1 << i][i][0] = dp[1 << i][i][1] = 1 ;
}
for (int i = 0 ; i < 1 << n ; i ++ ){
for (int j = 0 ; j < n ; j ++ ){
for (int k = 0 ; k < j ; k ++ ){
if(i & (1 << j) == 0 || i & (1 << k) == 0)continue ;
dp[i][j][0] += dp[i ^ (1 << j)][k][1] ;
}
for (int k = j + 1 ; k < n ; k ++ ){
if(i & (1 << j) == 0 || i & (1 << k) == 0)continue ;
dp[i][j][1] += dp[i ^ (1 << j)][k][0] ;
}
}
}
ll cc = 0 ;
for (int i = 0 ; i < n ; i ++ ){
cc += dp[(1 << n) - 1][i][0] ;
cc += dp[(1 << n) - 1][i][1] ;
// cout << dp[(1 << n) - 1][i][0] << " fuck " << endl;
}
return cc ;
}
int main(){
for (int i = 0 ; i <= 20 ; i ++ ){
cout <<i << " : " << get(i) << endl;
}
return 0 ;
}
0 : 0
1 : 1
2 : 2
3 : 4
4 : 10
5 : 32
6 : 122
7 : 544
8 : 2770
9 : 15872
10 : 101042
11 : 707584
12 : 5405530
13 : 44736512
14 : 398721962
15 : 3807514624
16 : 38783024290
17 : 419730685952
18 : 4809759350882
19 : 58177770225664
20 : 740742376475050
G,HDU过了UVA过不了。
这题数据范围都没给,HDU 上开到10就可以了。
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 0x3fffffff
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
using namespace std;
inline void RD(int &ret) {
char c;
int flag = 1 ;
do {
c = getchar();
if(c == '-')flag = -1 ;
} while(c < '0' || c > '9') ;
ret = c - '0';
while((c=getchar()) >= '0' && c <= '9')
ret = ret * 10 + ( c - '0' );
ret *= flag ;
}
inline void OT(int a) {
if(a >= 10)OT(a / 10) ;
putchar(a % 10 + '0') ;
}
/*********************************************/
#define D 20
string OP[6] = {"A" , "B" , "C" , "a" , "b" ,"c"} ;
bool vis[D][D][D] ;
int inmap(int x ,int y ,int z) {
if(x >= 0 && y >= 0 && z >= 0 && x < D && y < D && z < D)return 1 ;
return 0 ;
}
#define N 100005
struct kdq {
int x , y , z ;
string op ;
kdq() {
op.clear() ;
}
void init(int _x ,int _y,int _z ) {
x = _x ;
y = _y ;
z = _z ;
}
} qe[N] ;
int n , m ;
int sx , sy , sz , ex ,ey ,ez ;
int a[3][3] ;
void bfs() {
mem(vis, 0) ;
vis[sx][sy][sz] = 1 ;
kdq st ;
st.init(sx , sy , sz) ;
int h = 0 , t = 0 ;
qe[h ++ ] = st ;
while(h > t) {
kdq tp = qe[t ++ ] ;
if(tp.x == ex && tp.y == ey && tp.z == ez) {
cout << tp.op.size() <<" " << tp.op << endl;
return ;
}
if(tp.x > 0) {
int tx = tp.x + a[0][0] ;
int ty = tp.y + a[0][1] ;
int tz = tp.z + a[0][2] ;
tx -- ;
if(inmap(tx, ty,tz) && !vis[tx][ty][tz]) {
kdq now ;
now.init(tx ,ty ,tz) ;
now.op = tp.op + OP[0] ;
qe[h ++ ] = now ;
vis[tx][ty][tz] = 1 ;
}
}
if(tp.y > 0) {
int tx = tp.x + a[1][0] ;
int ty = tp.y + a[1][1] ;
int tz = tp.z + a[1][2] ;
ty -- ;
if(inmap(tx, ty,tz) && !vis[tx][ty][tz]) {
kdq now ;
now.init(tx ,ty ,tz) ;
now.op = tp.op + OP[1] ;
qe[h ++ ] = now ;
vis[tx][ty][tz] = 1 ;
}
}
if(tp.z > 0) {
int tx = tp.x + a[2][0] ;
int ty = tp.y + a[2][1] ;
int tz = tp.z + a[2][2] ;
tz -- ;
if(inmap(tx, ty,tz) && !vis[tx][ty][tz]) {
kdq now ;
now.init(tx ,ty ,tz) ;
now.op = tp.op + OP[2] ;
qe[h ++ ] = now ;
vis[tx][ty][tz] = 1 ;
}
}
for (int i = 0 ; i < 3 ; i ++ ) {
if(tp.x >= a[i][0] && tp.y >= a[i][1] && tp.z >= a[i][2]) {
int tx = tp.x - a[i][0] ;
int ty = tp.y - a[i][1] ;
int tz = tp.z - a[i][2] ;
if(i == 0)tx ++ ;
if(i == 1)ty ++ ;
if(i == 2)tz ++ ;
if(inmap(tx ,ty ,tz) && !vis[tx][ty][tz]) {
kdq now ;
now.init(tx ,ty, tz) ;
now.op = tp.op + OP[i + 3] ;
qe[h ++ ] = now ;
vis[tx][ty][tz] = 1 ;
}
}
}
}
cout << "NO SOLUTION" << endl;
return ;
}
int main() {
int T ;
// freopen("D:\\acm.txt","r",stdin) ;
cin >> T ;
while(T -- ) {
RD(n) ;
RD(m) ;
cout << n << " " << m << endl;
for (int i = 0 ; i < 3 ; i ++ ) {
for (int j = 0 ; j < 3 ; j ++ )scanf("%d",&a[i][j]) ;
}
for (int i = 1 ; i <= m ; i ++ ) {
int ca ;
RD(ca) ;
scanf("%d%d%d%d%d%d",&sx,&sy,&sz,&ex,&ey,&ez) ;
cout << ca << " ";
bfs() ;
}
}
return 0 ;
}
J,水题
char fk[11111] ;
char f[1111] ;
int main() {
int T ;
cin >> T ;
while( T -- ){
int n ;
cin >> n ;
getchar() ;
gets(fk) ;
int m ;
cin >> m ;
int now = 0 ;
int d ;
int l = strlen(fk) ;
for (int i = 0 ; i < m ; i ++ ){
scanf("%d",&d) ;
now += d ;
now = (now + l ) % l ;
f[i] = fk[now] ;
}
f[m] = '\0' ;
cout <<n << " " << f << endl;
}
return 0 ;
}