您的位置:首页 > 大数据 > 人工智能

2015 Multi-University Training Contest 4

2015-08-03 22:31 155 查看

1001

打表下就能过。但是比赛的时候开始没打表tle了两次。之后写了个dp的。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

int dp[20][1<<10][2];
int A, B;
int digit[20], tot;

int dfs( int pos, int st, int f1, int f2 ){
if( pos < 0 ){
return 1;
}
if( !f1 && dp[pos][st][f1] != -1 ){
return dp[pos][st][f1];
}
int ans = 0;
int ed = f1 ? digit[pos] : 9;
for( int i = 0; i <= ed; i++ ){
if( i == 0 ){
if( f2 == 1 ){
ans += dfs( pos - 1, st, f1 && i == ed, f2 );
}else{
if( st & ( 1 << i ) )   continue;
ans += dfs( pos - 1, st | 1, f1 && i == ed, 0 );
}
}else{
if( st & ( 1 << i ) )   continue;
ans += dfs( pos - 1, st | ( 1 << i ), f1 && i == ed, 0 );
}
}
return dp[pos][st][f1] = ans;
}

int solve( int x ){
tot = 0;
while( x ){
digit[tot++] = x % 10;
x /= 10;
}
return dfs( tot - 1, 0, 1, 1 );
}

int main(){
int T;
scanf( "%d", &T );
memset( dp, -1, sizeof( dp ) );
while( T-- ){

scanf( "%d%d", &A, &B );
printf( "%d\n", solve( B ) - solve( A - 1 ) );
}
return 0;
}


1002

扫一遍就好

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

struct Node{
int a, b;
bool operator==( Node &A ) const{
if( a == A.a && b == A.b ){
return true;
}
return false;
}
};

int num[1100000], N;
int AP[1100000];
Node GP[1100000];

int gcd( int a, int b ){
return b == 0 ? a : gcd( b, a % b );
}

int main(){
int T;
scanf( "%d", &T );
while( T-- ){
scanf( "%d", &N );
for( int i = 0; i < N; i++ ){
scanf( "%d", &num[i] );
}
if( N == 1 ){
printf( "1\n" );
continue;
}
int ans = 1;
int pre = num[1] - num[0], cnt = 1;
for( int i = 2; i < N; i++ ){
AP[i] = num[i] - num[i-1];
if( AP[i] == pre ){
cnt++;
ans = max( ans, cnt );
}else{
pre = AP[i];
ans = max( ans, cnt );
cnt = 1;
}
}
cnt = 1;
Node temp,temp1;
int tt = gcd( num[1], num[0] );
temp.a = num[1] / tt;
temp.b = num[0] / tt;
for( int i = 2; i < N; i++ ){
tt = gcd( num[i], num[i-1] );
temp1.a = num[i] / tt;
temp1.b = num[i-1] / tt;
if( temp1 == temp ){
cnt++;
ans = max( ans, cnt );
}else{
temp = temp1;
ans = max( ans, cnt );
cnt = 1;
}
}
printf( "%d\n", ans + 1 );
}
return 0;
}


1008

构造题

1 1 1 2 2 2 3 3 3….

设第i个的长度为Li

sum(Li) = L

那么这个序列的子序列个数为:

(L+1)* L/2 - sum(Li *(Li - 1 ))

于是现在就有两个方程:

sum(Li) = N

(L+1)* L/2 - sum(Li *(Li-1)) = K

=>sum(Li * (Li-1)) = (L+1)* L/2 - K

我们可以先不管第一个方程,对于第二个方程,我们对于每一个Li,我们让Li尽可能大,这样当前几个就能满足和为(L+1)* L/2 - K时,其余的全部取1就行

这种方法要注意的是当k为4 和16的时候解不出来

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

long long cnt[111000], tot;
long long K;

void dfs( long long len, long long num ){
if( num == 0 ){
while( len-- ){
cnt[tot++] = 1;
}
return;
}
long long l = 1, r = len + 1, mid;
while( l <= r ){
mid = ( l + r ) / 2;
if( mid * ( mid - 1 ) <= num ){
l = mid + 1;
}else{
r = mid - 1;
}
}
mid = r;
while( mid * ( mid - 1 ) <= num ){
cnt[tot++] = mid;
num -= mid * ( mid - 1 );
len -= mid;
}
dfs( len, num );
}

int main(){
while( scanf( "%I64d", &K ) != EOF ){
if( K <= 100 ){
cout << K <<endl;
while( K-- ){
printf( "1 " );
}
puts("");
continue;
}
long long l = 1;
tot = 0;
while( l * ( l + 1 ) < 2 * K ){
l++;
}
dfs( l, l * ( l + 1 ) - 2 * K );
printf( "%I64d\n", l );
for( int i = 0; i < tot; i++ ){
for( int j = 0; j < cnt[i]; j++ ){
printf( "%d ", i + 1 );
}
}
puts("");
}
return 0;
}


1009

搜索

首先用个bfs搜最接近右下角的0

然后从这些0出发一层一层的搜结果,对于每层搜索,如果有0,只保存0的分支,否则全部保存

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
using namespace std;

int moves[][2] = { { 0, 1}, { 0, -1 }, { 1, 0 }, { -1, 0 } };
int movess[][2] = { { 0, 1}, { 1, 0 } };
char mp[1001][1001];
int N, M;
int pre[1001][1001];
bool mark[1001][1001];
int ansmp;
char anss[1001];
int ans[1001], tot;
void bfs(){

tot = 0;
memset( mark, false, sizeof( mark ) );
ansmp = 0;
mark[0][0] = true;
queue<int> q;
// q.clear();
q.push( 0 );
while( !q.empty() ){
int n = q.front();
q.pop();
int nx = n / M;
int ny = n % M;
if( mp[nx][ny] == '1' ){
continue;
}
for( int i = 0; i < 4; i++ ){
int tempx = nx;
int tempy = ny;
tempx += moves[i][0];
tempy += moves[i][1];
if( tempx < 0 || tempx >= N || tempy < 0 || tempy >= M ){
continue;
}
if( mark[tempx][tempy] ){
continue;
}
if( mp[tempx][tempy] == '1' ){
continue;
}
mark[tempx][tempy] = true;
q.push( tempx * M + tempy );
if( tempx + tempy > ansmp / M + ansmp % M ){
tot = 0;
ans[tot++] = tempx * M + tempy;
ansmp = tempx * M + tempy;
}else if( tempx + tempy == ansmp / M + ansmp % M  ){
ans[tot++] = tempx * M + tempy;
}
}
}
}
void bfs2(){
if( tot == 1 && ans[tot] / M == N - 1 && ans[tot] % M == M - 1 ){
puts( "") ;
}
queue<int> q1;
while( !q1.empty() ){
q1.pop();
}
queue<int> q2;
while( !q2.empty() ){
q2.pop();
}
for( int i = 0; i < N; i++ ){
for( int j = 0; j < M; j++ ){
pre[i][j] = -1;
}
}
memset( mark, false, sizeof( mark ) );
if( tot == 0 ){
q1.push( 0 );
pre[0][0] = -1;
mark[0][0] = true;
}else{
for( int i = 0; i < tot; i++ ){
for( int j = 0; j < 2; j++ ){
int tx = ans[i] / M;
int ty = ans[i] % M;
tx += movess[j][0];
ty += movess[j][1];
if( tx < 0 || ty < 0 || tx >= N || ty >= M ){
continue;
}
if( mark[tx][ty] ){
continue;
}
q1.push( tx * M + ty );
mark[tx][ty] = true;
}
}
}
while( !q1.empty() ){
int SZ = q1.size();
int flag = 0;
int cc = 0;
while( SZ-- ){
int n = q1.front();
q1.pop();
for( int i = 0; i < 2; i++ ){
int tx = n / M;
int ty = n % M;
tx += movess[i][0];
ty += movess[i][1];
if( tx < 0 || ty < 0 || tx >= N || ty >= M ){
continue;
}
if( mark[tx][ty] ){
continue;
}
if( flag == 0 ){
if( mp[tx][ty] == '0' ){
while( !q2.empty() ){
q2.pop();
}
q2.push(tx * M + ty);
pre[tx][ty] = n;
mark[tx][ty] = true;
flag = 1;
}else{
q2.push(tx * M + ty);
mark[tx][ty] = true;
pre[tx][ty] = n;
}
}else{
if( mp[tx][ty] == '1' ){
continue;
}else{
q2.push( tx * M + ty );
pre[tx][ty] = n;
mark[tx][ty] = true;
}
}
}
}
while( !q2.empty() ){
q1.push( q2.front() );
q2.pop();
}
}
int huzi = 0;
int ttx = N - 1;
int tty = M - 1;
while( 1 ){
anss[huzi++] = mp[ttx][tty];
if( pre[ttx][tty] == -1 ){
break;
}
int tt = pre[ttx][tty];
ttx = tt / M;
tty = tt % M;
}
int pp = huzi - 1;
while( anss[pp] == '0' ) pp--;
if( pp < 0 ){
puts("0");
return;
}
for( ; pp >= 0; pp-- ){
printf( "%c", anss[pp] );
}
puts("");
}

int main(){
int T;
scanf( "%d", &T );
while( T-- ){
scanf( "%d%d", &N, &M );
for( int i = 0; i < N; i++ ){
scanf( "%s", mp[i] );
}
bfs();
//tot = 0;
bfs2();
}
return 0;
}
/*
111
2 2
11
11

000000
111110
000000
011111
2 5
11111
00111

1111111
1011111
1110111
1111101
1101101
*/


1010

模拟题

注意下细节就好了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;

struct Node{
int p, dir;
};

int moves[][2] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };

int cnt[11000], id[11000];
int pos[110], ti[110];
int R, C, N, T;

int main(){
while( scanf( "%d%d%d%d", &R, &C, &N, &T ) != EOF ){
memset( cnt, 0, sizeof( cnt ) );
memset( id, -1, sizeof( id ) );
for( int i = 0; i < N; i++ ){
int temp1, temp2, temp3;
scanf( "%d%d%d", &temp1, &temp2, &temp3 );
pos[i] = ( temp1 - 1 ) * C + temp2 - 1;
cnt[pos[i]] = temp3;
id[pos[i]] = i;
}
int temp1, temp2;
scanf( "%d%d", &temp1, &temp2 );
int st = ( temp1 - 1 ) * C + temp2 - 1;
queue<int> q1;
queue<Node> q2;
while( !q1.empty() ) q1.pop();
while( !q2.empty() ) q2.pop();
q1.push( st );
int nowtime = 1;
while( nowtime <= T ){
queue<int> q3;
queue<Node> q4;
while( !q3.empty() ) q3.pop();
while( !q4.empty() ) q4.pop();
set<int> sets;
sets.clear();
while( !q1.empty() ){
int tx = q1.front() / C;
int ty = q1.front() % C;
q1.pop();
for( int i = 0; i < 4; i++ ){
int newtx = tx + moves[i][0];
int newty = ty + moves[i][1];
if( newtx < 0 || newty < 0 || newtx >= R || newty >= C )
continue;
Node temp;
temp.p = newtx * C + newty;
temp.dir = i;
if( cnt[temp.p] > 0 ){
cnt[temp.p]++;
if( cnt[temp.p] >4 ){
q3.push( temp.p );
sets.insert(temp.p);
cnt[temp.p] = 0;
ti[id[temp.p]] = nowtime;
}
}else if( sets.find( temp.p ) == sets.end() ){
q4.push( temp );
}
}
}
while( !q2.empty() ){
int tx = q2.front().p / C;
int ty = q2.front().p % C;
int dir = q2.front().dir;
q2.pop();
// for( int i = 0; i < 4; i++ ){
int newtx = tx + moves[dir][0];
int newty = ty + moves[dir][1];
if( newtx < 0 || newty < 0 || newtx >= R || newty >= C )
continue;
Node temp;
temp.p = newtx * C + newty;
temp.dir = dir;
if( cnt[temp.p] > 0 ){
cnt[temp.p]++;
if( cnt[temp.p] >4 ){
q3.push( temp.p );
cnt[temp.p] = 0;
sets.insert(temp.p);
ti[id[temp.p]] = nowtime;
}
}else if( sets.find( temp.p ) == sets.end() ){
q4.push( temp );
}
//  }
}
while( !q3.empty() ){
q1.push( q3.front() );
q3.pop();
}
while( !q4.empty() ){
q2.push( q4.front() );
q4.pop();
}
nowtime++;
}
for( int i = 0; i < N; i++ ){
if( cnt[pos[i]] <= 0 ){
printf( "%d %d\n", 0, ti[i] );
}else{
printf( "%d %d\n", 1, cnt[pos[i]] );
}
}
}
return 0;
}
/*
4 4 5 11
3 2 2
3 3 4
3 4 4
4 2 3
4 3 4
4 4

4 4 3 10
3 1 3
3 2 4
3 4 4
4 2
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: