2014 编程之美

第一题同构不会。

第二题比较容易,用总的情况减去有两个一样的情况,然后每次算乘法之前对 10^9+7取模

#include <stdio.h>
#include <string.h>

long long limit = 1000000007;
int main()
{
int testcase;
scanf(“%d”, &testcase);
for(int i = 1; i <= testcase; i++)
{
long long  n;
scanf(“%lld”, &n);
if(n >= limit)
n = n%limit;
long long t = n*(n+1)/2;
long long right = t-2*n+2;
if(right >= limit)
right = right%limit;
if(t >= limit)
t = t%limit;
long long left = t*t;
if(left >= limit)
left = left%limit;
long long res = left * right;
if(res >= limit)
res = res%limit;
printf(“Case %d: %lld\n”, i, res); 
}
}

第三题 据说要用匈牙利算法,表示没有学过,用的dfs+剪枝 AC了

#include <stdio.h>
#include <string.h>

#define MAXSIZE 101
int used[MAXSIZE][MAXSIZE];
unsigned int mat[MAXSIZE][MAXSIZE];
int M, N;
int pointofRow[MAXSIZE];
int pointofCol[MAXSIZE];
int cantUseRow[MAXSIZE];
int cantUseCol[MAXSIZE];
unsigned int minSum = 0xffffffff;

struct point
{
int x;
int y;
};

int avail(int m, int n)
{
if(cantUseCol[n])
return 0;
if(pointofRow[m] > 0 && pointofCol[n] > 0)
return 0;
return 1;
}

int findNext(int m, int n, struct point *next)
{
int i = 0;
if(!cantUseRow[m])
{
for(i = n+1; i < N; i++)
{
if(avail(m, i))
{
next->x = m;
next->y = i;
return 0;
}
}
}
if(m == M-1)
{
next->x = M;
next->y = N;
return -1;
}
for(i = 0; i < N; i++)
{
if(avail(m+1, i))
{
next->x = m+1;
next->y = i;
return 0;
}
}
return -1;
}

void dfs(int m, int n, int sum)
{
int i = m;
int j = n;
struct point next ={0, 0};
while(findNext(i, j, &next) != -1)
{
i = next.x;
j = next.y;
if(i – m > 1)
return;
int tmpcantUseColm = cantUseCol[m];
int tmpcantUseColn = cantUseCol[j];
if(m == i)
{
cantUseCol[m] = cantUseCol[j] = 1;
}
int tmpcantUseRow[MAXSIZE] = {0};
memcpy(tmpcantUseRow, cantUseRow, sizeof(cantUseRow));
int k = 0;
for(; k < i; k++)
{
if(used[k][j])
{
cantUseRow[k] = cantUseRow[i] = 1;
}
}

used[i][j] = 1;
pointofRow[i]++;
pointofCol[j]++;
dfs(i, j, sum + mat[i][j]);
used[i][j] = 0;
pointofRow[i]–;
pointofCol[j]–;
cantUseCol[m] = tmpcantUseColm;
cantUseCol[j] = tmpcantUseColn;
memcpy(cantUseRow, tmpcantUseRow, sizeof(cantUseRow));
}
if(next.x == M && next.y  == N && m == M-1)
{
int flag = 1;
int t = 0;
for(; t < N; t++)
flag = flag && pointofCol[t];
if(sum < minSum && flag)
minSum = sum;
}
}

int main()
{
int testcase;
int i, j, t;
scanf(“%d”, &testcase);
for(t = 1; t <= testcase; t++)
{
scanf(“%d%d”, &M, &N);
memset(mat, 0, sizeof(mat));
memset(used, 0, sizeof(used));
memset(pointofRow, 0, sizeof(pointofRow));
memset(pointofCol, 0, sizeof(pointofCol));
memset(cantUseCol, 0, sizeof(cantUseCol));
memset(cantUseRow, 0, sizeof(cantUseRow));
minSum = 0xffffffff;
for(i = 0; i < M; i++)
{
for(j = 0; j < N; j++)
{
scanf(“%d”, &mat[i][j]);
}
}
for(i = 0; i < N; i++)
{
used[0][i] = 1;
pointofRow[0]++;
pointofCol[i]++;
dfs(0, i, mat[0][i]);
used[0][i] = 0;
pointofRow[0]–;
pointofCol[i]–;
}
printf(“Case %d: %d\n”, t, minSum);
}
}

谁能给个同构的做法,完全不懂 = = 是图里面的东西吗…

点赞