20201105枚举课后总结
枚举
#210733. 奶牛碑文
题目描述
小伟暑假期间到大草原旅游,在一块石头上发现了一些有趣的碑文。碑文似乎是一个神秘古老的语言,只包括三个大写字母
C
、O
和W
。尽管小伟看不懂,但是令他高兴的是,C
、O
、W
的顺序形式构成了一句他最喜欢的奶牛单词“COW”
。现在,他想知道有多少次COW
出现在文本中。如果COW
内穿插了其他字符,只要COW
字符出现在正确的顺序,小伟也不介意。甚至,他也不介意出现不同的COW
共享一些字母。例如,CWOW
出现了1次COW
,CCOW
算出现了2次COW
,CCOOWW
算出现了8次COW
。
输入格式
输入包括一行仅仅包括
"C","O","W"
的字符串
输出格式
输出
COW
作为输入字符串的子序列出现的次数(不一定是连续的)。提示:答案会很大,建议用 64 位整数(long long)。
样例输入
CCCOOW
样例输出
6
思路
#1
枚举遍历计算C的个数,C之后O的个数和O之后W的个数,所有字符个数相乘即可(乘法原理)
#2
时间复杂度O(n)遍历字符串,统计C的个数,统计完C的个数则就能求出CO的个数,统计完CO最后就能求出COW的个数,逐次递进
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
ll len,ans,cntC,cntCO;
int main(){
cin>>s;
len=s.size();
for(int i=0;i<len;i++){
if(s[i]=='C'){
cntC++;
}else if(s[i]=='O'){
cntCO+=cntC;
}else if(s[i]=='W'){
ans+=cntCO;
}
}
printf("%lld",ans);
return 0;
}
#210792. 分解质因数
题目描述
正整数分解为质因式,输出如下形式:如
\[\begin{eqnarray} 2=2\\ 3=3\\ 4=2^2\\ 10=2\times 5\\ 100=2^2 \times 5^2 \end{eqnarray} \]
输入格式
输入一行,包含一个正整数\(n\)
输出格式
输出\(n\)的质因式表达, 要求质因数是从小到大的
样例
样例输入#1
2
样例输出#1
2=2
样例输入#2
100
样例输出#2
100=2^2*5^2
数据范围与提示
\[\begin{eqnarray} 2\leq n \leq 10^9 \end{eqnarray} \]
思路
使用试除法(如果这个数为2的倍数,就不用再去除4了)。如果一个数的除数可以除多个,则计算个数,然后根据格式输出即可
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,cnt;
bool flag=true;
int main() {
scanf("%lld",&n);
printf("%lld=",n);
for(ll i=2;i<=sqrt(n);i++){
// ll x=i;
while(n%i==0){
// if(!flag)printf("*");
// printf("%lld",i);
cnt++;
n/=i;
}
if(cnt==1){
if(!flag)printf("*");
printf("%lld",i);
flag=false;
}else if(cnt>0){
if(!flag)printf("*");
printf("%lld^%lld",i,cnt);
flag=false;
}
cnt=0;
}
if(n!=1){
if(!flag)printf("*");
printf("%lld",n);
}
return 0;
}
#10213. 质因数分解升级版
题目描述
求出区间[a,b]中所有整数的质因数分解。
输入格式
输入两个整数a,b。
输出格式
每行输出一个数的分解,形如k=a1a2a3...(a1< =a2< =a3...,k也是从小到大的)(具体可看样例)
样例输入
3 10
样例输出
3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5
思路
与上题基本一致,从一个数变成了一个区间内的一个数
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b;
int main() {
scanf("%lld%lld",&a,&b);
for(ll i=a;i<=b;i++){
printf("%lld=",i);
ll x = i;
bool flag = true;
// 试除法
for (ll j = 2; j*j <= x; ++j)
{
while (x % j == 0) {
if (!flag) cout << "*";
printf("%lld", j);
flag = false;
x /= j;
}
}
if (x != 1) {
if (!flag) cout << "*";
printf("%lld\n", x);
}else{
printf("\n");
}
}
return 0;
}
#420. [NOI Online 入门组] 文具订购(本站数据)
题目描述
小明的班上共有\(n\)元班费,同学们准备使用班费集体购买\(3\)种物品:
圆规,每个\(7\)元。
笔,每支\(4\)元。
笔记本,每本\(3\)元。
小明负责订购文具,设圆规,笔,笔记本的订购数量分别为\(a,b,c\),他订购的原则依次如下:
\(n\)元钱必须正好用光,即\(7a+4b+3c=n\)
在满足以上条件情况下,成套的数量尽可能大,即\(a,b,c\)中的最小值尽可能大。
在满足以上条件情况下,物品的总数尽可能大,即\(a+b+c\)尽可能大。
请你帮助小明求出满足条件的最优方案。可以证明若存在方案,则最优方案唯一。
输入格式
输入仅一行一个整数,代表班费数量\(n\)。
输出格式
如果问题无解,请输出\(-1\)。
否则输出一行三个用空格隔开的整数\(a,b,c\)分别代表圆规、笔、笔记本的个数。
样例
样例输入#1
1
样例输出#1
-1
样例输入#2
14
样例输出#2
1 1 1
样例输入#3
33
样例输出#3
1 2 6
数据范围与提示
样例数据#3解释
\(a=2,b=4,c=1\)也是满足条件\(1,2\)的方案,但对于条件\(3\),该方案只买了\(7\)个物品,不如\(a=1,b=2,c=6\)的方案。
数据规模与约定
思路
枚举a和b,计算出c,判断如果加和为n,则表明有解,再根据题目条件,求解最优解,记录,最后如有解则输出,无解则输出-1.
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,ansa=-1,ansb=-1,ansc=-1,sum;
bool f;
int main(){
scanf("%lld",&n);
if(n<3){
printf("-1");
return 0;
}
for(ll a=n/7;a>=0;a--){
for(ll b=(n-7 * a)/4;b>=0;b--){
ll c=(n-7 * a-4*b)/3;
if(7*a+4*b+3*c==n) {
f=true;
ll cur=min(a,min(b,c));
ll ori=min(ansa,min(ansb,ansc));
// printf("%lld %lld %lld",a,b,c);
// break;
if(cur>ori||cur==ori&&a+b+c>sum){
ansa=a;
ansb=b;
ansc=c;
sum=a+b+c;
}
}
}
}
if(!f)printf("-1");
else{
printf("%lld %lld %lld",ansa,ansb,ansc);
}
return 0;
}