AtCoder Beginner Contest 293 C~E
c:
There is a grid with H horizontal rows and W vertical columns. For two integers i and j such that 1≤i≤H and 1≤j≤W, the square at the i-th row from the top and j-th column from the left (which we denote by (i,j)) has an integer Ai,j written on it.
Takahashi is currently at (1,1). From now on, he repeats moving to an adjacent square to the right of or below his current square until he reaches (H,W). When he makes a move, he is not allowed to go outside the grid.
Takahashi will be happy if the integers written on the squares he visits (including initial (1,1) and final (H,W)) are distinct. Find the number of his possible paths that make him happy.
题意:从(1,1)走到(n,m),每次都只能向下或向右走,一共有多少路径上的值都只出现一次
思路:dfs遍历就可以了
代码:
#include <bits/stdc++.h>
#define int long long
const int N = 20;
int a[N][N];
int n,m;
int ans = 0;
void dfs(int u,int v,std::map<int,int>mp1)
{
mp1[a[u][v]]++;
if(u == n&&v == m)
{
for(auto[l,r]:mp1)
{
if(r > 1)
return;
}
ans ++;
}
if(u+1<=n)
{
// if(mp1[a[u+1][v]] >= 1)
// return ;
//mp1[a[u+1][v]]++;
dfs(u+1,v,mp1);
//mp1[a[u+1][v]]--;
}
if(v+1<=m)
{
// if(mp1[a[u][v+1]] >= 1)
// return ;
//mp1[a[u][v+1]]++;
dfs(u,v+1,mp1);
//mp1[a[u][v+1]]--;
}
}
void solve()
{
std::cin >> n >> m;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
std::cin >> a[i][j];
}
std::map<int,int>s;
// s[a[1][1]]++;
dfs(1,1,s);
std::cout << ans << '\n';
}
signed main()
{
solve();
}
D
There are N ropes numbered 1 through N. One end of each rope is painted red, and the other is painted blue.You are going to perform M operations of tying ropes. In the i-th operation, you tie the end of rope Ai painted Bi with the end of rope Ci painted Di, where R means red and B means blue. For each rope, an end with the same color is not tied multiple times.
Find the number of groups of connected ropes that form cycles, and the number of those that do not, after all the operations.
Here, a group of connected ropes {v0,v1,…,vx−1} is said to form a cycle if one can rearrange the elements of v so that, for each 0≤i<x, rope vi is tied to rope v(i+1)modx.
题意:给你n个绳子,m条边,输出一共有多少个联通块
思路:并查集,把相连的用并查集搞一下,然后遍历看看有多少个块,再判断这个块是不是每个数出现了两次
代码:
#include <bits/stdc++.h>
#define int long long
const int N = 2e5 + 10;
int a[N];
int f[N];
int n,m;
int find(int x)
{
if(x!=f[x])
{
f[x] = find(f[x]);
}
return f[x];
}
void solve()
{
std::cin >> n >> m;
std::map<int,int>mp;
std::set<int>se,se1;
for(int i = 1;i <= n;i ++)
{
f[i] = i;
}
for(int i = 1;i <= m;i ++)
{
int x,y;
std::string l,r;
std::cin >> x >> l >> y >> r;
f[find(x)] = find(y);
mp[x]++;
mp[y]++;
}
for(int i = 1;i <= n;i ++)
{
//std::cout << find(i) << '\n';
se.insert(find(i));
if(mp[i]<2)
se1.insert(find(i));
}
// for(auto[l,r]:mp)
// {
// if(r == 2)
// se1.insert(find(l));
// }
std::cout << se.size() - se1.size() << ' ' << se1.size() << '\n';
}
signed main()
{
solve();
}
E
Given integers A, X, and M, find i=0∑X−1Ai, modulo M.
题意:求a的(x-1)次方的和
思路:很明显的等比数列求和公式,但是我们不可以直接套公式,例如:3 2 2这个样例
所以我们可以用分治法推出这个公式
p0+p1+…+pk/2−1+pk/2+pk/2+1+…+pk−1
p0+p1+…+pk/2−1+pk/2∗(p0+p1+…+pk/2−1)
原因可以看我的博客数任:约数 - 清初 - 博客园 (cnblogs.com)
代码:
#include <bits/stdc++.h>
#define int long long
const int N = 2e5 + 10;
int n,t,m;
int qmid(int a,int b)
{
a %= m;
int res = 1;
while(b) {
if(b & 1) res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}
int sum(int p, int k) {
if(k == 1) return 1;
if(k % 2 == 0) {
return (int)(qmid(p, k / 2) + 1) * sum(p, k / 2) % m;
}
return (qmid(p, k - 1) + sum(p, k - 1)) % m;
}
void solve()
{
std::cin >> n >> t >> m;
if(n == 1)
{
std::cout << t%m << '\n';
return ;
}
int ans = sum(n,t)%m;
std::cout << (ans)%m << '\n';
}
signed main()
{
solve();
}