这两天主要是写了题组里面的题目和Java的学习,本来打算平均分配时间在刷题和学Java上的,结果因为几个题目一直写不出来,花了很长时间在刷题上面,Java学的很少。
先说一下这两天写的题:
https://vjudge.net/contest/547627#problem/B
这题刚开始的时候我只会判断能不能全部变成白色,方法是第一行不管,直接从第二行开始遍历,如果它的头上是黑色的话就要翻转;一直到最后一行遍历完后看最后一行是不是全是白色,如果不是则不能达到目的;这是判断的方法;
但是这题要求的是最优解,这就让我想了很久,于是我想到了第一行翻与不翻对结果时会有影响的;于是又难倒我了,如何判断第一行的某个元素到底要不要翻呢?,一看数据范围,m,n最多15;这还判断个毛线,直接遍历;由于此时我已经心累,就去csdn上面看了题解;
要看懂这段代码需要了解一些知识点;首先是1<<m;这个其实表示的是1*2^m;
flip[0][m-j-1]=i>>j&1;这句其实就是将第一行的翻转后的情况全部搞出来了;
第一行的结果已经出来,然后我们根据第一行的状态去判断能不能全白;并且记录翻转的次数;
#include<stdio.h>
int map[20][20];
int temp[20][20];//临时的翻转情况;
int ans[20][20];//最终的结果;
int nextx[5] = { 0, 1, -1, 0, 0 };
int nexty[5] = { 0, 0, 0, 1, -1 };
int m, n;
int get(int x, int y)//得到(x,y)的颜色;
{
int c = map[x][y];
for (int i = 0; i < 5; i++)
{
int tx = x + nextx[i];
int ty = y + nexty[i];
if(tx>=0&&tx<m&&ty>=0&&ty<n)
{
c += temp[tx][ty];
}
}
return c % 2;
}
int dfs()
{
for (int i = 1; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (get(i - 1, j))
{
temp[i][j] = 1;
}
}
}
for (int j = 0; j < n; j++)
{
if (get(m-1, j) == 1)
{
return -1;
}
}
int cnt = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cnt += temp[i][j];
}
}
return cnt;
}
int main()
{
scanf("%d%d", &m, &n);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &map[i][j]);
}
}
int rns = -1, num = 0;
for (int i = 0; i < 1 << m; i++)
{
for (int k = 0; k < 20; k++)
{
for (int j = 0; j < 20; j++)
{
temp[k][j] = 0;
}
}
for (int j = 0; j < m; j++)
{
temp[0][j] = i >> j & 1;
}
num = dfs();
if (num >= 0 && (rns == -1 || num < rns))
{
rns = num;
for (int a = 0; a < m; a++)
{
for (int b = 0; b < n; b++)
{
ans[a][b] = temp[a][b];
}
}
}
}
if (rns == -1)
{
printf("IMPOSSIBLE\n");
}
else
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d%c", ans[i][j], j == n-1 ? '\n' : ' ');
}
}
}
return 0;
}
https://vjudge.net/contest/547627#problem/C
这题刚开始没想到用搜索的方法去写这道题;而是一直在那找规律;但是花了很长时间都没有找到一个很好的规律;然后我去问了郭浩怡同学;她告诉我要用搜索,而且是将0 1 所能表示的所有值储存在m中,然后再判断m%n是否为0;而且m中储存的数也是有规律的;
1 10 11 100 101 110 111 。。。。。
可以推出a[i] = a[i / 2] * 10 + i % 2;
然后我写完后信心满满的提交却得到答案错误,我又在细节方面改了几个后依然是答案错误;最无语的事情来了,我用一样的代码提交;不过把那语言换了一下;就过了,很是无语;
#include<stdio.h>
long long a[2000000];
int main()
{
int n;
while (1)
{
scanf("%d", &n);
a[1] = 1;
if (n == 0)
{
break;
}
for (int i = 1 ; ;i++)
{
a[i] = a[i / 2] * 10 + i % 2;
if (a[i] % n == 0)
{
printf("%lld\n", a[i]);
break;
}
}
}
return 0;
}
https://vjudge.net/contest/547627#problem/D
这题我是一遍过的;我是用了一个字符串来储存A+B的结果;然后再进行操作,如果过程中有一个结果与S相同,就输出结果;如果操作操作着又回到了A+B则说明没有解;不多说了,我感觉是这题组中最简单的一题了;
#include<stdio.h>
#include<string.h>
int t, len;
char s1[105], s2[105], s[205], temps[205], ts[205];
int main()
{
scanf("%d", &t);
int T = t;
while (t--)
{
for (int i = 0; i < 105;i++)
{
s1[i] = '\0';
s2[i] = '\0';
}
for (int i = 0; i < 205; i++)
{
s[i] = '\0';
temps[i] = '\0';
ts[i] = '\0';
}
scanf("%d", &len);
scanf("%s", s1);
scanf("%s", s2);
scanf("%s", s);
strcpy(ts, s1);
strcat(ts, s2);
int flag = 0;
int cnt = 0;
do
{
cnt++;
for (int i = 0; i < 2 * len; i++)
{
if (i % 2 == 0)
{
temps[i] = s2[i / 2];
}
else
{
temps[i] = s1[i / 2];
}
}
if (strcmp(temps, s) == 0)
{
flag = 1;
printf("%d %d\n", T - t, cnt);
break;
}
for (int i = 0; i < 2 * len; i++)
{
if (i < len)
{
s1[i] = temps[i];
}
else
{
s2[i-len] = temps[i];
}
}
} while (strcmp(ts, temps) != 0);
if (flag == 0)
{
printf("%d -1\n", T - t);
}
}
return 0;
}
写的题还有两个,暂时不总结了;接下来分享一下这两天学的Java;
因为这两天被题目坑了很多次,就跟题目杠上了,没怎么学Java,后面两天,周六我准备花比较长的时间去学习Java;