主要是卡了一下 接下来2题还在做 都有思路
1001
考虑全然即可了
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
__int64 n, m, v, k;
scanf("%I64d %I64d %I64d %I64d", &n, &m, &v, &k);
if(m >= n)
{
puts("0");
continue;
}
if(k <= 1 || m <= v || (m-v)*k == m)
{
puts("-1");
continue;
}
int sum = 0;
while(m < n && m >= 0)
{
sum++;
m = (m-v)*k;
}
if(m <= 0 && m < n)
sum = -1;
printf("%d
", sum);
}
return 0;
}
1002
1003
这题错了半天 伤不起 转成字符串搞字典树就错 最后直接位运算&建树就对了
AC代码
#include <cstdio>
#include <cstring>
typedef __int64 LL;
const int maxn = 100010;
const int maxnode = 60000000;
const int sigma_size = 2;
LL a[maxn];
char s[maxn][70];
int ch[maxnode][sigma_size];
LL val[maxnode];
int sz;
void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void insert(LL v)
{
int u = 0;
for(int i = 31; i >= 0; i--)
{
int c = (v&(1<<i)) == 0 ? 0 : 1;
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
}
void find(LL x)
{
LL ans = 0;
int u = 0;
for(int i = 31; i >= 0; i--)
{
int c = (x&(1<<i)) == 0 ? 0 : 1;
if(ch[u][c^1])
u = ch[u][c^1];
else
u = ch[u][c];
}
printf("%I64d
", val[u]);
}
int main()
{
int cas = 1;
int T;
scanf("%d", &T);
while(T--)
{
init();
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
{
scanf("%I64d", &a[i]);
insert(a[i]);
}
printf("Case #%d:
", cas++);
while(m--)
{
LL x;
scanf("%I64d", &x);
find(x);
}
}
return 0;
}
然后是错误代码
#include <cstdio>
#include <cstring>
const int maxn = 100010;
const int maxnode = 10000000;
const int sigma_size = 2;
__int64 a[maxn];
char s[maxn][70];
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void insert(char *s, __int64 x)
{
int u = 0, n = 60;
for(int i = 0; i < 35; i++)
{
int c = s[i] - '0';
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = x;
}
void find(char *s)
{
__int64 ans = 0;
int u = 0, n = 35;
for(int i = 0; i < 35; i++)
{
int c = s[i] - '0';
if(ch[u][c^1])
{
u = ch[u][c^1];
}
else
{
u = ch[u][c];
}
}
printf("%I64d
", val[u]);
}
int main()
{
int cas = 1;
int T;
scanf("%d", &T);
while(T--)
{
init();
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
{
scanf("%I64d", &a[i]);
int x = 35;
__int64 y = a[i];
s[i][x] = 0;
while(x--)
{
s[i][x] = y % 2 + '0';
y /= 2;
}
insert(s[i], a[i]);
//puts(s[i]);
}
printf("Case #%d:
", cas++);
while(m--)
{
__int64 y;
char str[60];
scanf("%I64d", &y);
int x = 35;
str[x] = 0;
while(x--)
{
str[x] = y % 2 + '0';
y /= 2;
}
//puts(str);
find(str);
}
}
return 0;
}
1004
简单递推一下
每个点能够由它左边过来然后在从这个点向上向下跟新最大值
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 110;
const int INF = 9999999;
int dp[maxn][maxn];
int a[maxn][maxn];
bool vis[maxn][maxn][3];
int main()
{
int cas = 1;
int T;
scanf("%d", &T);
while(T--)
{
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 0; j <= m; j++)
dp[i][j] = -INF;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
dp[1][1] = a[1][1];
memset(vis, false, sizeof(vis));
for(int i = 2; i <= n; i++)
dp[i][1] = dp[i-1][1] + a[i][1];
for(int i = 1; i < m; i++)
{
for(int j = 1; j <= n; j++)
{
int temp = dp[j][i] + a[j][i+1];
dp[j][i+1] = max(dp[j][i+1], temp);
int temp1 = temp;
for(int k = j-1; k >= 1; k--)
{
temp1 += a[k][i+1];
dp[k][i+1] = max(dp[k][i+1], temp1);
}
int temp2 = temp;
for(int k = j+1; k <= n; k++)
{
temp2 += a[k][i+1];
dp[k][i+1] = max(dp[k][i+1], temp2);
}
}
}
printf("Case #%d:
", cas++);
printf("%d
", dp[1][m]);
}
return 0;
}