三元组
给定 n 个三元组 (ai,bi,ci)。
所有给定三元组均满足 0≤ai,bi,ci≤1。
请你计算,共有多少个三元组满足 ai+bi+ci≥2ai+bi+ci≥2。
输入格式
第一行包含整数 nn。
接下来 nn 行,每行包含三个整数 ai,bi,ciai,bi,ci。
输出格式
一个整数,表示满足条件的三元组个数。
数据范围
前 33 个测试点满足 1≤n≤31≤n≤3。
所有测试点满足 1≤n≤10001≤n≤1000,0≤ai,bi,ci≤10≤ai,bi,ci≤1。
输入样例1:
3
1 1 0
1 1 1
1 0 0
输出样例1:
2
输入样例2:
2
1 0 0
0 1 1
输出样例2:
1
可以参考题意来暴力枚举我们可以把三个数都累加起来,如果它大于或等于2,计数;否则,不计,然后可以得出以下代码,然后输出计数器即可。 先写一个for/while循环一共0~n-1次 输入abc三个(临时的数即可)在一个if循环里增加计数器各一次,判断三元组符合条件。
for(i=1;i<=n;i++){
if(a[i]+b[i]+c[i]>=2)ans++;
}
最终的代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
int a[10000],b[10000],c[10000];
cin>>n;
int cnt = 0;
for(int i=0;i<n;i++){
cin>>a[i]>>b[i]>>c[i];
if(a[i]+b[i]+c[i]>=2){
cnt++;
}
}
cout<<cnt;
return 0;
}
最简单版的代码如下:
#include<bits/stdc++.h>
int n,a,b,c,cnt;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
if(a+b+c>=2) cnt++;
} printf("%d",cnt);
}
等差数列
给定一个长度为 nn 的正整数数列 a1,a2,…,ana1,a2,…,an 和一个正整数 kk。
你可以对数列进行以下两种操作:
+ i x
,增加操作,将 aiai 的值增加 xx(x≥1x≥1)。- i x
,减少操作,将 aiai 的值减少 xx(x≥1x≥1)。
要求:在任何时候,你都需要保证每个 aiai 的值都是正整数。
请你使用尽可能少的操作次数,使得数列能够满足:对于所有 ii(1≤i<n1≤i<n),ai+1−ai=kai+1−ai=k 均成立。
请你输出所需要的最少操作次数以及对应的具体操作方案。
输入格式
第一行包含两个整数 n,kn,k。
第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an。
输出格式
第一行输出一个整数 pp,表示所需要的最少操作次数。
接下来 pp 行,用来输出具体操作方案,每行输出一个具体操作 + i x
或 - i x
。你需要保证输出的 ii 和 xx 均为正整数,且 1≤i≤n1≤i≤n。
如果最少操作次数的方案不唯一,则输出任意一种方案均可。
数据范围
前 33 个测试点满足 1≤n≤71≤n≤7。
所有测试点满足 1≤n≤10001≤n≤1000,1≤k≤10001≤k≤1000,1≤ai≤10001≤ai≤1000。
输入样例1:
4 1
1 2 1 5
输出样例1:
2
+ 3 2
- 4 1
输入样例2:
4 1
1 2 3 4
输出样例2:
0
输入样例3:
7 1
1 1 2 3 4 5 6
输出样例3:
6
+ 2 1
+ 3 1
+ 4 1
+ 5 1
+ 6 1
+ 7 1
当数列的第一位确定,整个等差数列就确定了,所以直接枚举数列的第一位,我们要修改尽可能少的数去构造,所以最优解一定是与原本的数组最接近的数列。我们可以按照每一个数 x ,以x构造一个等差数列,用哈希表去储存 x 和 它的等差数列,用一个全局变量 去记录与原本数组最接近的数列,最后输出 数列和数组所差的值。
在构造的时候
1. 我们以x = 当前用来构造的数 u = x 在原本数组里的下标 i = 当前等差数列的下标 tmp[] =当前等差数列
2. tmp[u] = x, tmp[i] = x + (i - u) * k
3. 如果 tmp[i] <= 0 代表不合法解 直接return
最后直接根据题目要求输出就行了
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1005;
int a[N];
int n,k;
int op(int m){
int res=0;
for(int i=1;i<=n;i++){
if(a[m]-a[i]!=k*(m-i) && a[m]-k*(m-i)>0) res++;
if(a[m]-a[i]!=k*(m-i) && a[m]-k*(m-i)<=0) return 0x3f3f3f3f;
}
return res;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int x=1;
for(int i=2;i<=n;i++){
if(op(x)>op(i)) x=i;
}
printf("%d\n",op(x));
for(int i=1;i<=n;i++){
if(a[x]-a[i]!=k*(x-i)){
if(a[x]>a[i]+k*(x-i)) printf("+ %d %d\n",i,a[x]-(a[i]+k*(x-i)));
if(a[x]<a[i]+k*(x-i)) printf("- %d %d\n",i,a[i]+k*(x-i)-a[x]);
}
}
return 0;
}
卡牌
有 nn 张完全相同的卡牌,每张卡牌正面为红色,背面为蓝色。
初始时,将这 nn 张卡牌堆叠在一起,构成一个牌堆。
每张卡牌的颜色朝向是随机的,可能蓝色朝上,也可能红色朝上。
现在规定一种操作,该操作可以用来改变牌堆中卡牌的颜色朝向。
每一轮操作分为三个步骤:
- 如果位于牌堆顶部的卡牌是红色朝上,则将其从牌堆中拿出,置于手中。不断重复此过程,直到牌堆顶部的卡牌是蓝色朝上为止。
- 将位于牌堆顶部的卡牌翻面,即将该卡牌从蓝色朝上变为红色朝上。
- 如果手中存在卡牌,则将它们全部调整为蓝色朝上,并逐个放入牌堆顶部。
注意,该操作可以进行的前提是,执行操作前,牌堆中存在蓝色朝上的卡牌。
也就是说,如果牌堆中的 nn 张卡牌均为红色朝上,则该操作无法进行。
给定牌堆的初始状态,请你判断该牌堆最多可以重复进行多少轮上述操作。
输入格式
第一行包含一个整数 nn。
第二行包含一个长度为 nn 的字符串 SS,SS 中只包含 R
和 B
,用来描述牌堆的初始状态。SS 从左到右第 ii 个字符表示牌堆从上到下第 ii 张卡牌的朝上颜色,如果为 R
,则表示该卡牌红色朝上,如果为 B
,则表示该卡牌蓝色朝上。
输出格式
一个整数,表示给定牌堆可以进行的最大操作轮数。
数据范围
前 44 个测试点满足 1≤n≤51≤n≤5。
所有测试点满足 1≤n≤501≤n≤50。
输入样例1:
3
RBR
输出样例1:
2
输入样例2:
4
RBBR
输出样例2:
6
输入样例3:
5
RBBRR
输出样例3:
6
输入样例4:
1
R
输出样例4:
0
一道找规律的题,我们看题目中B出现的位置,经过一系列的推敲,我们就会发现这是2的幂之和,我们就可以得出以下代码。整个序列看成一个二进制序列,R 是 1,B 是 0,从左到右的顺序为最低位到最高位,求将当前二进制序列累加到 n 位二进制位都为 1 的序列的次数。即 n 位都为 1 的二进制序列与当前二进制序列的差值,这道题可以自己找几个样例试一下,会发现是其实就是二进制加法,每一步都是加 1 的操作 。
接下来完整代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int n;
ll sum;
char a[55];
while ( cin >> n )
{
sum = 0;
cin >> a;
for ( int i = 0; i < n; i++ ){
if ( a[i] == 'B')
sum += pow(2,i);
}
cout << sum << endl;
}
}