小A的文化节
#include<iostream>
using LL=long long;
using namespace std;
int a[100005],b[100005];
int main()
{
int cnt=0;
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int j=1;j<=m;j++)
{
cin>>b[j];
}
for(int j=1;j<=m;j++)
{
cnt+=a[b[j]];
}
cout<<cnt;
return 0;
}
小A的游戏
#include<iostream>
using LL=long long;
using namespace std;
LL x[1005],y[1005];
int main()
{
int a[3]={0,1,3};
int t;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>x[i]>>y[i];
if((y[i]-x[i])%3==0)
cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
小A的数字
#include<iostream>
using namespace std;
using LL=long long;
const LL mod=998244353;
int n,m,t,ans=0;
int a[100005];
int l[10],r[10];
void dfs(int x)
{
if(x>=m)//线段数量
{
for(int i=1;i<=n;i++)
{
if(a[i]<2) return ;
}
ans++;//
return ;
}
//统计次数
for(int i=l[x];i<=r[x];i++)
{
a[i]++;
}
dfs(x+1);
for(int i=l[x];i<=r[x];i++)
{
a[i]--;
}
dfs(x+1);
}
void solve()
{
cin>>n>>m;
for(int i=0;i<m;i++)
cin>>l[i]>>r[i];
dfs(0);
cout<<ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
t=1;
// cin>>t;
while(t--)
{
solve();
return 0;
}
}
假设有以下线段:
l[] = {1, 2, 3}
r[] = {3, 4, 5}
-
初始状态:初始时,
x = 0
,还没有考虑任何线段,数组a[]
中的计数都是初始值0。 -
第一次递归调用dfs函数:在初始状态下,调用
dfs(0)
,开始处理第一个线段。 -
处理第一个线段:假设第一个线段是从1到3,因此循环将
a[1]
、a[2]
、a[3]
的计数都加一。然后递归调用dfs(1)
,开始处理第二个线段。 -
处理第二个线段:假设第二个线段是从2到4,因此循环将
a[2]
、a[3]
、a[4]
的计数都加一。然后递归调用dfs(2)
,开始处理第三个线段。 -
处理第三个线段:假设第三个线段是从3到5,因此循环将
a[3]
、a[4]
、a[5]
的计数都加一。然后递归调用dfs(3)
。 -
达到递归终止条件:在第三个线段处理完毕后,
x = 3 >= m
,因此达到递归终止条件。这时候程序会返回上一层递归调用的位置,即dfs(2)
。 -
回溯:回到
dfs(2)
的位置,这时候需要进行回溯操作,将第二个线段覆盖的位置计数减一。所以循环将a[2]
、a[3]
、a[4]
的计数都减一。 -
第二次递归调用dfs函数:回溯完成后,再次调用
dfs(3)
,这次是不考虑第二个线段的情况。 -
达到递归终止条件:在第三个线段处理完毕后,同样达到递归终止条件,这时候程序会返回上一层递归调用的位置,即
dfs(1)
。 -
回溯:回到
dfs(1)
的位置,同样需要进行回溯操作,将第一个线段覆盖的位置计数减一。 -
第二次递归调用dfs函数:回溯完成后,再次调用
dfs(2)
,这次是不考虑第一个线段的情况。 -
达到递归终止条件:在第二个线段处理完毕后,同样达到递归终止条件,这时候程序会返回上一层递归调用的位置,即
dfs(0)
。 -
回溯:回到
dfs(0)
的位置,同样需要进行回溯操作,将初始线段覆盖的位置计数减一。 -
递归调用结束:回溯完成后,递归调用结束,整个递归过程结束。
初始状态:
n = 5, m = 4
a = [0, 0, 0, 0, 0] (表示每个位置的线段数量初始都为0)
l = [4, 1, 3, 1]
r = [5, 5, 5, 4]
ans = 0
调用 solve() -> dfs(0)
dfs(0):
当前处理的线段索引 x = 0
l[0] = 4, r[0] = 5
将位置 4 到 5 的线段数量加 1: a = [0, 0, 0, 1, 1]
调用 dfs(1)
dfs(1):
当前处理的线段索引 x = 1
l[1] = 1, r[1] = 5
将位置 1 到 5 的线段数量加 1: a = [1, 1, 1, 1, 1]
调用 dfs(2)
dfs(2):
当前处理的线段索引 x = 2
l[2] = 3, r[2] = 5
将位置 3 到 5 的线段数量加 1: a = [1, 1, 2, 2, 2]
调用 dfs(3)
dfs(3):
当前处理的线段索引 x = 3
l[3] = 1, r[3] = 4
将位置 1 到 4 的线段数量加 1: a = [2, 2, 3, 3, 2]
调用 dfs(4)
dfs(4):
当前处理的线段索引 x = 4 >= m
检查所有线段高度是否都大于等于 2,发现满足条件
ans++,此时 ans = 1
回溯操作,将位置 1 到 4 的线段数量减 1: a = [1, 1, 2, 2, 2]
回溯到 dfs(3)
继续尝试下一个线段组合
继续尝试下一个线段组合
回溯操作,将位置 3 到 5 的线段数量减 1: a = [1, 1, 1, 1, 1]
回溯到 dfs(2)
继续尝试下一个线段组合
继续尝试下一个线段组合
回溯操作,将位置 1 到 5 的线段数量减 1: a = [0, 0, 0, 0, 0]
回溯到 dfs(1)
继续尝试下一个线段组合
继续尝试下一个线段组合
回溯操作,将位置 4 到 5 的线段数量减 1: a = [0, 0, 0, 0, 0]
回溯到 dfs(0)
继续尝试下一个线段组合
所有线段组合尝试完毕,输出结果 ans = 1
假设我们有以下线段列表:a = [1, 1, 2, 2, 2]
。
-
初始状态:
a = [1, 1, 2, 2, 2]
-
第一次回溯,将位置 1 到 4 的线段数量减 1:
a = [1, 1, 1, 1, 2]
- 下一个线段组合:
[1, 1, 1, 1, 1]
-
第二次回溯,将位置 3 到 5 的线段数量减 1:
a = [1, 1, 1, 1, 1]
- 下一个线段组合:
[1, 1, 1, 0, 0]
-
第三次回溯,将位置 1 到 5 的线段数量减 1:
a = [0, 0, 0, 0, 0]
- 下一个线段组合:
[0, 0, 0, 0, 0]
-
第四次回溯,将位置 4 到 5 的线段数量减 1:
a = [0, 0, 0, 0, 0]
- 下一个线段组合:
[0, 0, 0, 0, 0]
因此,从第一次回溯开始,下一个线段组合依次为 [1, 1, 1, 1, 1]
,[1, 1, 1, 0, 0]
,[0, 0, 0, 0, 0]
,[0, 0, 0, 0, 0]
。