小C的倍数问题
Accepts: 1990
Submissions: 4931
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
手动模拟出以一到十几的数为p满足条件的所有数,然后会发现规律:p进制下,有且只有p-1所有的因子都满足条件,所以就是求p-1的所有因子个数。
代码:
#include <bits/stdc++.h>
using namespace std;
int solve(int n)
{
int ans = 0;
for(int i = 1; i*i <= n; ++i)
{
if(n%i == 0)
{
ans += 2;
if(i*i == n) --ans;
}
}
return ans;
}
int main()
{
int t, p;
scanf("%d", &t);
while(t--)
{
scanf("%d", &p);
printf("%d\n", solve(p-1));
}
return 0;
}
今夕何夕
Accepts: 1345
Submissions: 5533
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
类似蓝桥的一道题,直接分在2.29当天、之前、之后三种情况暴力向后推即可,没审好题,还考虑了之前的年份,白WA了一发。
代码:
#include <bits/stdc++.h>
using namespace std;
int ispre(int m, int d)
{
if(m == 2) return d < 29;
return m < 2;
}
int isrn(int y)
{
if(y%100 == 0) return y%400 == 0;
else return y%4 == 0;
}
int main()
{
int t, yy, mm, dd, cnt, ans, sum;
scanf("%d", &t);
while(t--)
{
scanf("%d-%d-%d", &yy, &mm, &dd);
if(mm == 2 && dd == 29)
{
ans = yy, sum = 0;
do
{
++ans;
if(isrn(ans)) sum += 366;
else sum += 365;
sum %= 7;
}
while(sum != 0 || !isrn(ans));
printf("%d\n", ans);
}
else if(ispre(mm, dd))
{
ans = yy, sum = 0;
do
{
++ans;
if(isrn(ans-1)) sum += 366;
else sum += 365;
sum %= 7;
}
while(sum != 0);
printf("%d\n", ans);
}
else
{
ans = yy, sum = 0;
do
{
++ans;
if(isrn(ans)) sum += 366;
else sum += 365;
sum %= 7;
}
while(sum != 0);
printf("%d\n", ans);
}
}
return 0;
}
度度熊的01世界
Accepts: 967
Submissions: 3064
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
其实感觉这题最简单,但是实验室停电+上面那题的智障操作,没来得及做这题。首先将所有外围的0全部"清掉"(标记),然后再标记一次一个1的连通块,由于外层的0全部清掉了,那么如果形状是零且没有多余的其它连通块,那么再找到的0就是1连通块内包含的0连通块,并进行标记,最后结合上面的各种标记,再检查一次是否存在未被标记的点,存在则说明存在多个1连通块,判-1即可,否则再判是0还是1。
代码:
#include <bits/stdc++.h>
using namespace std;
int nt[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
char mp[105][105];
int mark[105][105];
int n, m;
void dfs(int id, int x, int y)
{
mark[x][y] = id;
int tx, ty;
for(int i = 0; i < 4; ++i)
{
tx = x + nt[i][0];
ty = y + nt[i][1];
if(tx < 0 || ty < 0 || tx >= n || ty >= m) continue;
if(mp[x][y] != mp[tx][ty]) continue;
if(mark[tx][ty]) continue;
dfs(id, tx, ty);
}
}
int main()
{
int keys, flag;
while(~scanf("%d %d", &n, &m))
{
memset(mark, 0, sizeof mark);
for(int i = 0; i < n; ++i)
scanf("%s", mp[i]);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
{
if(mark[i][j]) continue;
if(mp[i][j] == '1') break;
dfs(1, i, j);
}
for(int i = n-1; i >= 0; --i)
for(int j = m-1; j >= 0; --j)
{
if(mark[i][j]) continue;
if(mp[i][j] == '1') break;
dfs(1, i, j);
}
for(int j = 0; j < m; ++j)
{
if(mark[0][j]) continue;
if(mp[0][j] == '0') dfs(1, 0, j);
}
for(int j = 0; j < m; ++j)
{
if(mark[n-1][j]) continue;
if(mp[n-1][j] == '0') dfs(1, n-1, j);
}
//上面全部为了清掉外围0
//寻找1连通块
flag = 1;
for(int i = 0; i < n && flag; ++i)
for(int j = 0; j < m && flag; ++j)
{
if(mp[i][j] == '1')
dfs(2, i, j), flag = 0;
}
if(flag) {puts("-1"); continue;}
//寻找内层0连通块
keys = 1;
for(int i = 0; i < n && keys; ++i)
for(int j = 0; j < m && keys; ++j)
{
if(!mark[i][j] && mp[i][j] == '0')
dfs(3, i, j), keys = 0;
}
//判是否有残余点
flag = 1;
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
if(!mark[i][j])
{
flag = 0; break;
}
if(flag)
{
if(keys) puts("1");
else puts("0");
}
else puts("-1");
}
return 0;
}
继续加油~