赞
踩
/* 日期差值 */ #include<bits/stdc++.h> using namespace std; int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int main() { int time1,time2; int y1,d1,m1,y2,d2,m2; cin>>time1>>time2; if(time1>time2){ swap(time1,time2); } y1=time1/1000,m1=time1%10000/100,d1=time1%100; y2=time2/1000,m2=time2%10000/100,d2=time2%100; int ans=1; while(y1<y2 || m1<m2 || d1<d2){ d1++; if((y1%4==0 &&y1%100!=0) || ( y1%400==0)){ month[2]=29; }else{ month[2]=28; } if(d1==month[m1]+1){ m1++; d1=1; } if(m1 == 13){ y1++; m1 = 1; } ans++; } cout<<ans; }
将P进制数x转化为十进制数y:
- int product = 1 , y = 0;
- while( x != 0)
- {
- y += (x%10)*product;
- x = x / 10;
- product = product * P;
- }
- cout<<y<<;
将十进制 y 转换为 Q 进制数 z
- int z[10], num = 0;
- do{
- z[num++] = y % Q ;
- y = y / Q ;
- }while(y != 0);
- for(int i = num - 1 ; i >= 0 ;i--){
- cout<<z[i];
- }
考虑到 2**3*5*7*11*13*17*19*23*29 就已经超过了 int 范围 ,因此只需要质数数组大小为10 就可以了
#include<bits/stdc++.h> using namespace std; int prime[10]={2,3,5,7,11,13,17,19,23,29}; int main() { int m; int a[101]; cin>>m; int k=0,num=0; while(m!=1) { if(m%prime[k]!=0){ k++; }else{ a[num++]=prime[k]; m/=prime[k]; } } for(int i=0 ;i<num;i++){ cout<<a[i]<<" "; } }
如果A和B是有着1000个数位的整数 , 恐怕就没有办法用已有的数据类型来表示了,这时就只能老实去模拟加减乘除的过程
#include<bits/stdc++.h> using namespace std; struct bign{ int d[1000]; int len; bign() //每次定义结构体变量时,都会自动对该变量进行初始化 { memset(d,0,sizeof(d)); len = 0; } }; bign change(char str[]){ //将整数转换为 bign bign a; a.len = strlen(str); //整数的高位变成数组的低位 //这样方便比较两个bign变量的大小 , 或者加减 for(int i=0 ; i<a.len ; i++){ a.d[i] = str[a.len - i -1] -'0'; //逆着赋值 } return a; } int main() { char s[1001]; cin>>s; bign a=change(s); }
#include<bits/stdc++.h> using namespace std; struct bign{ int d[1000]; int len; bign() //每次定义结构体变量时,都会自动对该变量进行初始化 { memset(d,0,sizeof(d)); len = 0; } }; bign change(char str[]){ //将整数转换为 bign bign a; a.len = strlen(str); //整数的高位变成数组的低位 for(int i=0 ; i<a.len ; i++){ a.d[i] = str[a.len - i -1] -'0'; //逆着赋值 } return a; } bign add(bign a ,bign b){ bign c; int carry = 0; // carry 是进位 for(int i = 0 ; i < a.len || i < b.len ;i++){ int temp =a.d[i] + b.d[i] +carry; c.d[c.len++] = temp % 10 ; carry = temp / 10; } if(carry != 0){ //遍历到最后一位 , 如果最后进位不为 0 ,则直接赋给结果的最高位 c.d[c.len++] = carry ; } return c; } int main() { char s1[1001],s2[1001]; cin>>s1>>s2; bign a=change(s1); bign b=change(s2); bign c=add(a,b); for(int i = c.len-1 ;i >= 0 ;i--){ cout<<c.d[i]; } }
#include<bits/stdc++.h> using namespace std; struct bign{ int d[1000]; int len; bign() //每次定义结构体变量时,都会自动对该变量进行初始化 { memset(d,0,sizeof(d)); len = 0; } }; bign change(char str[]){ //将整数转换为 bign bign a; a.len = strlen(str); //整数的高位变成数组的低位 for(int i=0 ; i<a.len ; i++){ a.d[i] = str[a.len - i -1] -'0'; //逆着赋值 } return a; } bign sub(bign a ,bign b){ bign c; int carry = 0; //155 //127 for(int i = 0 ; i<a.len || i<b.len ;i++){ if(a.d[i] < b.d[i]){ a.d[i+1]--; //向高位借位 a.d[i] += 10; //当前位加 10 } c.d[c.len++]=a.d[i] - b.d[i]; } while(c.len-1 >= 1 && c.d[c.len - 1] == 0){ c.len--; //去除高位的 0 ,同时至少保留一位最低位 } return c; //注意返回 } int main() { char s1[1001],s2[1001]; cin>>s1>>s2; bign a=change(s1); bign b=change(s2); bign c=sub(a,b); for(int i = c.len-1 ;i >= 0 ;i--){ cout<<c.d[i]; } }
/* 高精度乘法*/ #include<bits/stdc++.h> using namespace std; struct bign{ int d[1000]; int len; bign() //每次定义结构体变量时,都会自动对该变量进行初始化 { memset(d,0,sizeof(d)); len = 0; } }; bign change(char str[]){ //将整数转换为 bign bign a; a.len = strlen(str); //整数的高位变成数组的低位 for(int i=0 ; i<a.len ; i++){ a.d[i] = str[a.len - i -1] -'0'; //逆着赋值 } return a; } bign multi(bign a ,int b){ //注意是 int 因为 b 是低精度 bign c; int carry = 0; for(int i = 0; i<a.len; i++){ int temp = a.d[i]*b + carry; c.d[c.len++] = temp % 10; carry = temp / 10 ; } while(carry!=0){ //和加法不一样,乘法的进位可能不止一位,因此用while c.d[c.len++] = carry%10; carry /= 10 ; } return c; //注意返回 } int main() { char s1[1001]; cin>>s1; bign a=change(s1); int b; cin>>b; bign c=multi(a,b); for(int i = c.len-1 ;i >= 0 ;i--){ cout<<c.d[i]; } }
/* 高精度乘法*/ #include<bits/stdc++.h> using namespace std; struct bign{ int d[1000]; int len; bign() //每次定义结构体变量时,都会自动对该变量进行初始化 { memset(d,0,sizeof(d)); len = 0; } }; bign change(char str[]){ //将整数转换为 bign bign a; a.len = strlen(str); //整数的高位变成数组的低位 for(int i=0 ; i<a.len ; i++){ a.d[i] = str[a.len - i -1] -'0'; //逆着赋值 } return a; } bign divide(bign a ,int b){ //注意是 int 因为 b 是低精度 bign c; int r = 0; //被除数的每一位和商的每一位是一一对应的,因此先令长度相等 c.len = a.len ; for(int i=a.len-1 ; i>=0 ; i--){ r=r*10+a.d[i] ; //和上一位遗留的余数组合 if(r < b) c.d[i] = 0; //不移除,该位为 0 else{ c.d[i] = r / b; //商 r=r % b; //新余数 } } //去除高位 0 while(c.len - 1 >= 1 && c.d[c.len-1] == 0){ c.len--; } return c; //注意返回 } int main() { char s1[1001]; cin>>s1; bign a=change(s1); int b; cin>>b; bign c=divide(a,b); for(int i = c.len-1 ;i >= 0;i--){ cout<<c.d[i]; } }
- int cal(int n,int p)
- {
- int ans=0;
- for(int i=2 ;i<=n;i++){
- int temp = i;
- while(temp % p == 0){ //只要temp 还是 p 的倍数
- ans++;
- temp /= p;
- }
- }
- return ans;
- }
但如果 n 很大的时候 ,会严重超时的 ,所以需要寻求速度更快的方法。
- int cal(int n,int p)
- {
- int ans = 0;
- while(n){
- ans += n / p ;
- n /= p;
- }
- return ans;
- }
- long long C(long long n,long long m)
- {
- long long ans = 1;
- for(long long i = 1 ; i <= n ; i++){
- ans*=i;
- }
- for(long long i = 1 ; i <= m ; i++){
- ans /= i;
- }
- for(long long i = 1 ; i <= n-m ; i++){
- ans /= i;
- }
- return ans;
- }
- long long C(long long n,long long m)
- {
- if(m==0 || m==n ) return 1;
- return C(n-1 , m) +C(n - 1 , m - 1);
- }
- long long vis[100][100] = {0};
- long long C(long long n,long long m)
- {
- if(m==0 || m==n ) return 1;
- if(res[n][m] != 0) return res[n][m];
- return res[n][m] = C(n-1 , m) +C(n - 1 , m - 1);
- }
1.push_back()
- int main(){
- vector<int > vi;
- for(int i=0 ; i<=5 ;i++){
- vi.push_back(i);
- }
- for(int i=0 ;i<vi.size() ;i++){
- cout<<vi[i]<<" ";
- }
- }
- //输出 1 2 3
2.pop_back()
- int main(){
- vector<int > vi;
- for(int i=1 ; i<=3 ;i++){
- vi.push_back(i);
- }
- vi.pop_back(); //删除尾部元素
- for(int i=0 ;i<vi.size() ;i++){
- cout<<vi[i]<<" ";
- }
- }
- //输出 1 2
3.size()
4.clear() //清空所有元素
5.insert()
- int main(){
- vector<int > vi;
- for(int i=1 ; i<=3 ;i++){
- vi.push_back(i);
- }
- vi.insert(vi.begin() + 2 , -1); //将 -1 插入vi[2]的位置
- for(int i=0 ;i<vi.size() ;i++){
- cout<<vi[i]<<" ";
- }
- }
- //输出1 2 -1 3
6. erase()
用法一:删除单个元素 erase( it ) 即删除迭代器为 it 处的元素
- int main(){
- vector<int > vi;
- for(int i=1 ; i<=3 ;i++){
- vi.push_back(i);
- }
- vi.erase(vi.begin() + 1); //删除vi[1]的位置的元素
- for(int i=0 ;i<vi.size() ;i++){
- cout<<vi[i]<<" ";
- }
- }
- //输出 1 3
用法二:删除一个区间内的所有元素
erase( first , last )即删除 [ first , last )内的所有元素
- int main(){
- vector<int > vi;
- for(int i=1 ; i<=5 ;i++){
- vi.push_back(i);
- }
- vi.erase(vi.begin() + 1,vi.begin() + 3); //删除vi[1],vi[2]的位置的元素
- for(int i=0 ;i<vi.size() ;i++){
- cout<<vi[i]<<" ";
- }
- }
- // 输出 : 1 4 5
7. vi . begin( ) vi.end( )
- int main(){
- vector<int > vi;
- for(int i=1 ; i<=5 ;i++){
- vi.push_back(i);
- }
- //用迭代器 循环条件只能用 it != vi.end()
- for(vector<int>::iterator it = vi.begin() ; it != vi.end() ; it++ ){
- cout<<*it<<" "; //注意输出格式
- }
- }
- set<int> name ;
- set<double> name ;
- set<char> name ;
- set<node> name ; // node是结构体的类型
- int main(){
- set<int > st;
- st.insert(1);
- st.insert(1);
- st.insert(5);
- st.insert(3);
- //注意:不支持 it < st.end() 的写法
- for(set<int>::iterator it = st.begin() ; it != st.end() ; it++ ){
- cout<<*it<<" "; //注意输出格式
- }
- }
- //输出 1 3 5
- //set内的元素自动递增排序 ,且自动删除了重复元素
- int main(){
- set<int > st;
- for(int i=1 ; i<=5 ;i++){
- st.insert(i);
- }
- set<int>::iterator it = st.find(2); //返回迭代器
- cout<<*it;
- }
- //输出 2
- int main(){
- set<int > st;
- for(int i=1 ; i<=5 ;i++){
- st.insert(i);
- }
- st.erase(st.find(2)); //利用find() 函数找到 2,然后再删除它
- for(set<int>::iterator it = st.begin() ; it != st.end() ; it++ ){
- cout<<*it<<" ";
- }
- }
- //输出 1 3 4 5
- int main(){
- set<int > st;
- st.insert(20);
- st.insert(10);
- st.insert(40);
- st.insert(30);
- set<int>::iterator it = st.find(20);
- st.erase(it,st.end()); //删除元素 20 至set末尾之间的元素
- for(it = st.begin() ; it != st.end() ; it++ ){
- cout<<*it<<" ";
- }
- }
- //输出 10
- int main(){
- string s1 = "abc",s2 = "xyz";
- string s3 = s1 + s2;
- cout<<s3;
- }
- //输出 abcxyz
- int main(){
- string s1 = "aa" , s2 = "aaa";
- string s3 = "abc" , s4 = "xyz";
- if(s1<s2) cout<<"1"<<endl;
- if(s2<s3) cout<<"2"<<endl;
- }
s.erase( it ) 删除单个元素 , it 为迭代器
- int main(){
- string s1 = "abcdef" ;
- s1.erase(s1.begin()+2); //删除 2 号位
- cout<<s1;
- }
- //输出 abdef
- int main(){
- string s1 = "abcdef" ;
- s1.erase(s1.begin()+2 ,s1.begin()+4); //删除 [2,4)
- cout<<s1;
- }
- //输出abef
- int main(){
- string s1 = "abcdef" ;
- s1.erase(3,2); //删除从 3 号位开始的 2 个字符
- cout<<s1;
- }
- //输出abcf
- int main(){
- string str = "Thank you for your smile" ;
- cout<<str.substr(0,5)<<endl;
- cout<<str.substr(14,4)<<endl;
- cout<<str.substr(19,5)<<endl;
- }
- //Thank
- your
- smile
int main(){ string str = "Thank you for your smile" ; string str2 = "you"; string str3 = "me"; if(str.find(str2) != string::npos){ cout<< str.find(str2) << endl; } //从第七位开始找 if(str.find(str2 , 7) != string::npos){ cout<< str.find(str2, 7) << endl; } if(str.find(str3) != string::npos){ cout<< str.find(str3) << endl; }else{ cout<<"没有找到"<< endl; } } // 6 14 没有找到
- int main(){
- string str = "Thank you for your smile" ;
- string str2 = "me";
- cout << str.replace(6,3,str2);
- }
- //Thank me for your smile
- map<string , int > mp ;
- map<char , int > mp;
( 1 )通过下标访问
- int main(){
- map<char,int> mp;
- mp['c'] = 20;
- cout<<mp['c'];
- }
( 2 )通过迭代器访问
- int main(){
- map<char,int> mp;
- mp['c'] = 20;
- mp['m'] = 30;
- mp['a'] = 40;
- for(map<char,int>::iterator it = mp.begin();it!=mp.end();it++)
- {
- cout<<it->first<<" "<<it->second<<endl;;
- }
- }
- // a 40
- c 30
- m 20
注意的是:map会以从小到大的顺序自动进行排序。即按a < c < m;
- int main(){
- map<char,int> mp;
- mp['c'] = 20;
- mp['m'] = 30;
- mp['a'] = 40;
- map<char, int>::iterator it = mp.find('a');
- cout<<it->first<<" "<<it->second;
- }
- int main(){
- map<char,int> mp;
- mp['c'] = 20;
- mp['m'] = 30;
- mp['a'] = 40;
- map<char, int>::iterator it = mp.find('a');
- mp.erase(it); //删除 a , 40
- // 或者写成: mp.erase('a');
- for(map<char,int>::iterator it=mp.begin() ;it!=mp.end();it++)
- cout<<it->first<<" "<<it->second<<endl;
- }
- //
- c 20
- m 30
- int main(){
- map<char,int> mp;
- mp['b'] = 30;
- mp['a'] = 20;
- mp['c'] = 40;
- map<char, int>::iterator it = mp.find('b');
- mp.erase(it,mp.end()); //删除 it 之后的所有映射
- for(map<char,int>::iterator it=mp.begin() ;it!=mp.end();it++)
- cout<<it->first<<" "<<it->second<<endl;
- }
- // a 20
queue<... > name;
- int main(){
- queue<int> q;
- for(int i=1 ; i<=5 ;i++){
- q.push(i);
- }
- cout<<q.front()<<" "<<q.back();
- }
- // 1 5
- int main(){
- queue<int> q;
- for(int i=1 ; i<=5 ;i++){
- q.push(i); // 1 2 3 4 5依次入队
- }
- for(int i=1 ; i<=3 ;i++){
- q.pop(); //1 2 3依次出队
- }
- cout<<q.front(); // 输出 4
- }
如果为空返回 true
如果想让队列总是把最小的元素放在队首:只需如下定义:
- priority_queue< int , vector<int> ,greater<int>> q;
- q.push(3);
- q.push(4);
- q.push(1);
- cout<<q.top();
- //输出 1
可以对水果的名称和价格建立一个结构体
- struct fruit{
- string name;
- int price;
- };
struct fruit{ string name; int price; }f1,f2,f3; struct cmp{ bool operator () (fruit f1,fruit f2){ return f1.price > f2.price; } }; //优先队列的这个函数与sort函数中的cmp函数的效果是相反的 int main(){ priority_queue<fruit, vector<fruit> , cmp> q; f1.name = "桃子"; f1.price = 3; f2.name = "梨子"; f2.price = 4; f3.name = "苹果"; f3.price = 1; q.push(f1); q.push(f2); q.push(f3); cout<<q.top().name<<" "<<q.top().price<<endl; } // 输出 苹果 1
习题:
#include<bits/stdc++.h> using namespace std; struct cmp{ bool operator()(pair<int,int>& p1 , pair<int,int>& p2){ return p1.second > p2.second; } }; int main() { int nums[9] = {1,1,1,2,2,3,3,3,3}; int k = 2; unordered_map<int,int> map; for(int i = 0 ; i < 9 ;i++){ map[nums[i]]++; } priority_queue< pair<int,int>, vector<pair<int,int>> , cmp> q; for(auto it = map.begin() ; it!=map.end() ;it++){ q.push(*it); if(q.size()>k){ q.pop(); } } for(int i = 0 ; i< k ;i++){ cout<<q.top().first; q.pop(); } }
stack 翻译为栈 ,是STL中实现一个后进后出的容器。
stack< ... > name;
- int main()
- {
- stack<int> st;
- for(int i=1 ;i<=5 ;i++){
- st.push(i); //push(i)可以把 i 压入栈
- }
- cout<<st.top();
- }
- // 输出 :5
- //pair< typeName1 , typeName2 > name;
- pair< string , int > p;
- pair< string , int > p("haha" ,5 );
pair中只有两个元素 , 分别是first 和 second , 只需要按正常结构体的方式与访问即可 。
- int main()
- {
- pair<string, int> p;
- p.first = "haha";
- p.second = 5;
- cout<<p.first<<" "<<p.second<<endl;
- p = make_pair("xixi",55);
- cout<<p.first<<" "<<p.second<<endl;
- p = pair<string, int>("heihei",555);
- cout<<p.first<<" "<<p.second<<endl;
- }
- // 输出: haha 5
- xixi 55
- heihei 555
a. 用来代替二元结构体及其构造函数
b.作为map 的键值对来进行插入,例如下面的例子
- int main()
- {
- map<string, int> mp;
- mp.insert(make_pair("hhhh",5));
- mp.insert(pair<string, int>("haha", 10));
- for(map<string, int>::iterator it = mp.begin(); it!=mp.end() ;it++){
- cout<<it->first<<" "<<it->second<<endl;
- }
- }
- // hhhh 5
- haha 10
- int main()
- {
- int a[10]={10,11,12,13,14,15};
- reverse(a, a + 4); //将 a[0] ~ a[3]进行反转
- for(int i=0 ;i< 6;i++){
- printf("%d ",a[i]);
- }
- }
- // 输出 :13 12 11 10 14 15
- int main()
- {
- int a[5]={1,2,3,4,5};
- fill(a, a + 5,233); //将 a[0] ~ a[4]均赋值为 233
- for(int i=0 ;i< 5;i++){
- printf("%d ",a[i]);
- }
- }
对数组进行初始化
- int main(){
- int x[5];
- memset(x, 1, sizeof(x));
- for(int i=0; i<5; i++){
- printf("%d ", x[i]);
- }
- return 0;
- }
- bool cmp(char a , char b){
- return a > b;
- }
- int main()
- {
- char c[]={'b','a','d','c'};
- sort(c,c + 4,cmp);
- for(int i=0 ;i< 4;i++){
- printf("%c ",c[i]);
- }
- }
- // 输出 :d c b a
#include<bits/stdc++.h> using namespace std; struct node{ int x,y; }a[10]; //按照 x 从大到小排序 bool cmp(node a,node b){ return a.x > b.x; } int main() { a[0].x = 2; a[0].y = 2; // { 2 , 2 } a[1].x = 1; a[1].y = 3; // { 1 , 3 } a[2].x = 3; a[2].y = 1; // { 3 , 1 } sort( a ,a+3,cmp); for(int i = 0 ;i < 3 ;i++){ cout<<a[i].x<<" "<<a[i].y<<endl; } } // 输出 :3 1 2 2 1 3
- //按照 x 从大到小排序 ,如果 x 相等
- //按照 y 的大小从小到大来排序
- bool cmp(node a,node b){
- if(a.x != b.x) return a.x > b.x;
- else return a.y < b.y;
- }
以走迷宫为例,DFS 会搜遍所有的路径,即遇到不碰死胡同不回头。这样就是说:深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法。
#include<bits/stdc++.h> using namespace std; int n,v; int w[10],c[10]; int maxValue = 0; void dfs(int index,int sumW,int sumC){ //a代表第几个物品,sum代表现在容量总和 //先写终止条件 if(index == n){ //已经完成对 n 件物品的选择(死胡同) if(sumW <= v && sumC > maxValue){ maxValue = sumC; } return; } //不选该物品 dfs(index+1 , sumW , sumC); //选择该物品 dfs(index+1 , sumW+w[index] , sumC+c[index]); } int main() { cin>>n; cin>>v; //最大容量 for(int i=0;i<n;i++){ cin>>w[i]; //重量 } for(int i=0 ;i<n;i++){ cin>>c[i]; //价值 } dfs(0,0,0); cout<<maxValue; }
优化:
- void dfs(int index,int sumW,int sumC){ //a代表第几个物品,sum代表现在容量总和
- if(index == n){
- return;
- }
- //不选择第 index 件物品
- dfs(index+1 , sumW ,sumC );
- //只有加入第index件物品后未超过容量 V,才能继续
- if(sumW + w[index] <= v){
- if(sumC + c[index] > maxValue){
- maxValue = sumC + c[index];
- }
- //选第 index 件物品
- dfs(index+1 ,sumW + w[index] ,sumC + c[index]);
- }
- }
给定 N 个整数 ( 可能有负数 ),从中选择K个数,使得这K个数之和恰好等于一个给定的整数X;如果有多种情况,选择它们中元素平方和最大的一个。例如 : 从4个整数{2,3,3,4}中选择 2 个数 ,使它们的和为 6 ,显然有两种方案{ 2 ,4 } 与 {3 ,3} ,其中平方和最大的方案为{ 2 , 4 };
#include<bits/stdc++.h> using namespace std; int n,k,x; int a[10]; int maxSum = 0; vector<int> temp,ans; //ans为最优方案的数组 void dfs(int index ,int sumK,int sum,int powSum){ if(sumK==k && sum == x){ //找到 k 个数的和为 x if(powSum > maxSum){ maxSum = powSum; ans = temp; } return; } //已经处理完 n 个数,或者超过 k个数 ,或者和超过 x 返回 if(index==n || sumK >k || sum>x) return; //选择 index 号数 temp.push_back(a[index]); dfs(index+1,sumK+1,sum+a[index],powSum+pow(a[index],2)); temp.pop_back(); //不选择 index 号数 dfs(index+1,sumK,sum,powSum); } int main() { cin>>n; cin>>k; cin>>x; for(int i = 0 ; i<n ; i++){ cin>>a[i]; } dfs(0,0,0,0); for(int i=0 ;i<k;i++){ cout<<ans[i]<<" "; } }
#include<bits/stdc++.h> using namespace std; int n; int res = 0; //存方案数 int arr[20]; //存临时方案 int mem[59055][20]; //存所有方案 //index 表示当前枚举到哪一位 // sum表示当前调料的总质量 void dfs(int sum,int index){ if(sum > n ) return; if(index > 10){ if(sum == n){ res++; for(int i=1 ;i<=10 ;i++){ mem[res][i] = arr[i]; } } return; } for(int i=1 ; i<=3 ;i++){ arr[index] = i; dfs(sum+i,index+1); arr[index] = 0; } } int main() { cin>>n; dfs(0,1); cout<<res<<endl; for(int i = 1 ; i <= res; i++){ for(int j=1 ; j<=10 ;j++){ cout<<mem[i][j]<<" "; } cout<<endl; } } // 12345 12354 12435 12453 12534 12543
#include<bits/stdc++.h> using namespace std; int res = 0; int n; int arr[101]; int a[10]={6,2,5,5,4,5,6,3,7,6}; int nums(int num){ if(num < 10){ return a[num]; }else{ int x=0; //这是对于比如 A = 11 这种多位数来计算火柴根数 while(num){ x+=a[num%10]; num/=10; } return x; } } //注意两个条件 : // 1. A + B = C // 2. 指定火柴棒数 void dfs(int index , int sum){ if(sum> n) return; //如果当前火柴数已经多了,则剪枝 if(index > 3){ //表示都选完了,并对此进行判断 //满足两个条件时 if(arr[1] + arr[2]==arr[3] && sum == n){ res++; } return; } //对于题目中说最多有20跟火柴 可以知道极限为1000 for(int i=0 ;i<=1000;i++){ arr[index]=i; dfs(index+1,sum+nums(i)); arr[index]=0; } } int main() { cin>>n; n=n-4; dfs(1,0); cout<<res; }
对于计算火柴棍数可以进行优化 因为比如当计算199 对应的火柴棍数时,199/10=19 而19的火柴棍数在之前已经被算过了,不用费时间再算了。
#include<bits/stdc++.h> using namespace std; int res = 0; int n; int arr[101]; int a[1001]={6,2,5,5,4,5,6,3,7,6}; //注意两个条件 : // 1. A + B = C // 2. 指定火柴棒数 void dfs(int index , int sum){ if(sum> n) return; //如果当前火柴数已经多了,则剪枝 if(index > 3){ //表示都选完了,并对此进行判断 //满足两个条件时 if(arr[1] + arr[2]==arr[3] && sum == n){ res++; } return; } for(int i=0 ;i<=1000;i++){ arr[index]=i; dfs(index+1,sum+a[i]); arr[index]=0; } } int main() { cin>>n; n=n-4; //递推出 10 ~ 1000 需要用到的火柴棍 for(int i = 10 ;i<=1000 ;i++){ a[i]=a[i%10]+a[i/10]; } dfs(1,0); cout<<res; }
#include<bits/stdc++.h> using namespace std; int minNum = 0x7fffffff; //0x7fffffff 就表示 是一个十六进制的int的最大值 int n; int s[15],b[15]; void dfs(int index ,int suan,int ku) { if(index > n){ //必须判断清水的情况 if(suan==1 && ku==0) return; //更新最小值 minNum = min(abs(suan-ku),minNum); return; } // 选 dfs( index+1 , suan*s[index] , ku+b[index]); // 不选 dfs(index+1,suan,ku); } int main() { cin>>n; for(int i=1; i<=n ; i++){ cin>>s[i] >>b[i]; } dfs(1,1,0); cout<<minNum; }
#include<bits/stdc++.h> using namespace std; int n,a,b; int res = 0; int minNum = 0x7fffffff; int k[202]; bool vis[205]; void dfs(int begin,int num){ if(num >= minNum) return; if(begin == b){ // if(num < minNum){ // minNum = num; // } // 每次我都按上面写都不能得出答案 minNum = min(minNum,num); return; } vis[begin] = 1; //下楼 if(begin - k[begin] > 0 && !vis[begin - k[begin]]){ vis[begin - k[begin]] = 1; dfs(begin-k[begin],num+1); vis[begin - k[begin]] = 0; //回溯 } //上楼 if(begin + k[begin] <= n && !vis[begin + k[begin]]){ vis[begin + k[begin]] = 1; dfs(begin+k[begin],num+1); vis[begin + k[begin]] = 0; //回溯 } } int main() { cin>>n>>a>>b; for(int i=1 ; i<=n ; i++){ cin>>k[i]; } dfs(a,0); if(minNum == 0x7fffffff ){ cout<<"-1"; return 0; } cout<<minNum; }
DFS正确入门方式 | DFS + 递归与递推习题课(下) | 一节课教你爆搜!_哔哩哔哩_bilibili
#include<bits/stdc++.h> using namespace std; int m,n,h,k; char ch[22][22]; int res = 1; bool vis[22][22]; // 用数组来表示上下左右的情况 int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; void dfs(int x, int y ) { for(int i=0 ;i<4;i++){ //枚举四个坐标 int xx = dx[i] + x; int yy = dy[i] + y; if(ch[xx][yy]=='.'&& vis[xx][yy]!=true ){ res++; vis[xx][yy]=true; //设为已经走过的路 dfs(xx,yy); } } return; } int main() { cin>>m>>n; for(int i=1 ; i <= n ;i++){ for(int j=1 ; j <= m ;j++){ cin>>ch[i][j]; if(ch[i][j]=='@'){ h=i,k=j; } } } dfs(h,k); cout<<res; }
#include<bits/stdc++.h> using namespace std; char ch[102][102]; bool vis[101][101]; int n,m,res=0; int dx[8]={-1,-1,-1,0,1,1,1,0}; int dy[8]={-1,0,1,1,1,0,-1,-1}; void dfs(int x , int y) { for(int i = 0 ; i < 8 ; i++){ int xx = x + dx[i]; int yy = y + dy[i]; if(ch[xx][yy]=='W' && !vis[xx][yy]){ vis[xx][yy] = true; dfs(xx,yy); }else{ continue; } } } int main() { cin>>n>>m; for(int i =0 ; i < n ; i++){ for(int j = 0 ; j < m ; j++ ){ cin>>ch[i][j]; vis[i][j] = false; } } for(int i = 0 ; i < n ; i++){ for(int j = 0 ; j < m ; j++ ){ if(!vis[i][j] && ch[i][j]=='W'){ dfs(i,j); res++; } } } cout<<res; }
#include<bits/stdc++.h> using namespace std; int n,k,cnt = 0,res; char ch[10][10]; bool vis[10]; //表示搜索每一行 void dfs(int x , int cnt){ if(cnt == k){ res++; return ; } if(x >= n) return; for(int i=0 ; i<n ;i++){ if( ch[x][i]=='#' && !vis[i]){ vis[i] = true; dfs(x+1,cnt+1); vis[i] = false; } } dfs( x+1 , cnt ); } int main() { while(scanf("%d%d",&n,&k)){ if(n == -1 && k == -1) break; for(int i = 0; i < n ; i++) { for(int j = 0 ; j < n ; j++){ cin>>ch[i][j]; } } res = 0; dfs(0,0); cout<<res<<endl; } }
#include<bits/stdc++.h> using namespace std; int n,k; int res=0; int arr[101]; void dfs( int x , int start ,int nowSum) { if(nowSum > n) return; if(x > k){ if(nowSum == n){ res++; } return; } for(int i = start ; i<=n ;i++){ dfs( x+1 , i , nowSum + i); } } int main() { cin>>n>>k; dfs(1,1,0); cout<<res; }
若要打印方案:
#include<bits/stdc++.h> using namespace std; int n,k; int res=0; int arr[101]; void dfs( int x , int start ,int nowSum) { if(nowSum > n) return; if(x > k){ if(nowSum == n){ res++; for(int i = 1 ;i <= k ;i++){ cout<<arr[i]; } cout<<endl; } return; } for(int i = start ; i<=n ;i++){ arr[x] = i ; dfs( x+1 , i , nowSum + i); arr[x] = 0; //回溯 } } int main() { cin>>n>>k; dfs(1,1,0); cout<<res; }
#include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 21; int n; string word[N]; int g[N][N];//两个单词重合部分最小长度 int used[N];//单词使用次数 int ans; string d; void dfs(string dragon, int last) //last表示结尾用的单词 { if(dragon.size() > ans){ ans = dragon.size(); d=dragon; } used[last] ++ ; for (int i = 0; i < n; i ++ ) if (g[last][i] != 0 && used[i] < 2){ dfs(dragon + word[i].substr(g[last][i]), i); used[last] -- ; //回溯减一 } int main() { cin >> n; for (int i = 0; i < n; i ++ ) cin >> word[i]; char start; cin >> start; for (int i = 0; i < n; i ++ ) for (int j = 0; j < n; j ++ ) { string a = word[i], b = word[j]; //重合部分的长度,但其长度必须大于等于1,且严格小于两个串的长度 for (int k = 1; k < min(a.size(), b.size()); k ++ ) if (a.substr(a.size() - k, k) == b.substr(0, k)) { g[i][j] = k; break; } } for (int i = 0; i < n; i ++ ) if (word[i][0] == start) dfs(word[i], i); cout << ans << endl; return 0; }
#include<bits/stdc++.h> using namespace std; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int mp[10][10]; int fx,fy,sx,sy,ans=0,n,m,T,l,r; //int minX = 0x7fffffff; int vis[10][10]={false}; void dfs(int x,int y){ if(x==fx && y==fy){ ans++; return; } for(int i = 0 ; i < 4 ; i++){ int xx = x + dx[i]; int yy = y + dy[i]; if(mp[xx][yy]==1 && !vis[xx][yy]&&xx>=1&&xx<=n&&yy>=1&&yy<=m){ vis[xx][yy] = true; dfs(xx,yy); vis[xx][yy] = false; } } } int main() { cin>>n>>m>>T; for(int i= 1 ; i<=n;i++){ for(int j =1 ; j<=m ;j++){ mp[i][j]=1; } } cin>>sx>>sy; cin>>fx>>fy; for(int i = 1 ; i<=T ;i++){ cin>>l>>r; //障碍坐标 mp[l][r] = 0; } vis[sx][sy]=1;//起点算重复 (一定要写!!!) dfs(sx,sy); cout<<ans; }
#include<bits/stdc++.h> using namespace std; string letterMap[10] = { "", // 0 "", // 1 "abc", // 2 "def", // 3 "ghi", // 4 "jkl", // 5 "mno", // 6 "pqrs", // 7 "tuv", // 8 "wxyz" // 9 }; string digits; vector<string> result; void dfs(int index , string s) { if(index == digits.size()){ result.push_back(s); return; } int digit = digits[index] - '0'; string letters = letterMap[digit]; for(int i = 0 ; i < letters.size() ;i++){ s.push_back(letters[i]); dfs(index+1,s); s.pop_back(); } } int main() { cin>>digits; dfs(0,""); for(int i = 0 ; i < result.size() ;i++){ cout<<result[i]<<" "; } }
#include<bits/stdc++.h> using namespace std; vector<string> path; vector<vector<string> > result; string s; bool isPalindrome(int start, int end) { for (int i = start, j = end; i < j; i++, j--) { if (s[i] != s[j]) { return false; } } return true; } void dfs(int start) { if(start >= s.size()){ result.push_back(path); return; } for(int i = start ; i < s.size() ;i++){ if(isPalindrome(start,i)){ string str = s.substr(start,i-start+1); path.push_back(str); }else{ continue; } dfs(i+1); path.pop_back(); } } int main() { cin>>s; dfs(0); for(int i = 0 ; i < result.size() ;i++){ vector<string > cmp = result[i]; for(int j = 0 ; j <cmp.size() ;j++ ){ cout<<cmp[j]<<" "; } cout<<endl; } }
- void BFS( int s )
- {
- queue<int> q;
- q.push(s); //将起点s入队
- while(!q.empty()){
- 取出队首元素 top;
- 访问队首元素 top;
- 将队首元素出队;
- 将top的下一层结点中未曾入队的结点全部入队,并设置为已入队;
- }
- }
如果用dfs来写:
#include<bits/stdc++.h> using namespace std; int m,n,res = 0; int a[10][10]; bool vis[10][10]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,1,-1}; void dfs(int x,int y){ for(int i = 0 ; i < 4 ; i++){ int xx = x+dx[i]; int yy = y+dy[i]; if(a[xx][yy]==1 && !vis[xx][yy]){ vis[xx][yy]=true; dfs(xx,yy); }else{ continue; } } } int main() { cin>>m>>n; for(int i=1 ; i <= m ; i++){ for(int j=1 ; j <= n ; j++){ cin>>a[i][j]; } } for(int i=1 ; i <= m ; i++ ){ for(int j = 1 ; j <= n ; j++ ){ if(a[i][j]==1 && !vis[i][j]){ dfs(i,j); res++; } } } cout<<res; }
如果用BFS来写:
#include<bits/stdc++.h> using namespace std; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int a[10][10]; int m,n,ans=0; bool vis[10][10]={false}; struct node{ int x; int y; }Node; void bfs(int x,int y){ queue<node> Q; Node.x = x , Node.y = y; Q.push(Node); while(!Q.empty()){ node top = Q.front();//取出队首元素 Q.pop(); //队首元素再出队 for(int i = 0 ; i < 4 ;i++){ int xx = top.x + dx[i]; int yy = top.y + dy[i]; if(!vis[xx][yy] && a[xx][yy] == 1){ //设置Node新坐标 Node.x = xx; Node.y = yy; vis[xx][yy]=true; Q.push(Node); //将结点Node加入队列 } } } } int main() { cin>>m>>n; for(int i=0 ; i<m ;i++){ for(int j=0 ; j<n ;j++){ cin>>a[i][j]; } } for(int i = 0 ; i < m ; i++){ for(int j = 0 ; j < n ; j++){ if(a[i][j]==1 && !vis[i][j]){ ans++; bfs(i,j); } } } cout<<ans; }
#include<bits/stdc++.h> using namespace std; const int N = 110; int g[N][N]; int dx[4] = {-1,0,1,0}; int dy[4] = {0,1,0,1}; typedef pair<int,int> PII; int d[N][N]; int m,n; int bfs(){ queue<PII> q; PII t = {0,0}; q.push(t); while(!q.empty()){ auto pp = q.front(); q.pop(); for(int i = 0 ;i < 4 ;i++){ int x = pp.first + dx[i]; int y = pp.second + dy[i]; if(x >= 0 && x < n && y >= 0 && y < m && g[x][y]==0 && d[x][y]==-1 ){ d[x][y] = d[pp.first][pp.second]+ 1; q.push({x,y}); } } } return d[n-1][m-1]; } int main() { cin>>n>>m; for(int i = 0 ; i < n ;i++){ for(int j = 0; j < m ; j++){ cin>>g[i][j]; } } memset(d,-1,sizeof(d)); d[0][0] = 0; cout<<bfs()<<endl; }
dfs:
#include<bits/stdc++.h> using namespace std; int n,m; int dx[4] = {0,0,1,-1}; int dy[4] = {-1,1,0,0}; int a[102][102]; bool vis[102][102]; int minStep = 0x7fffffff; void dfs(int x , int y,int step){ if(x < 0 || x >= n || y < 0 || y >= m) return; if(x==n-1 && y==m-1){ minStep = min(minStep,step); return; } for(int i = 0 ; i < 4 ;i++ ){ int xx = x + dx[i]; int yy = y + dy[i]; if(a[xx][yy]==0 && !vis[xx][yy]) { vis[xx][yy] = true; dfs(xx,yy,step+1); vis[xx][yy] = false; //注意写这个 } } } int main() { cin>>n>>m; for(int i = 0 ; i < n ;i++){ for(int j = 0 ; j < m ;j++){ cin>>a[i][j]; } } dfs(0,0,0); cout<<minStep; }
#include<bits/stdc++.h> using namespace std; const int N = 1100; char g[N][N]; int dx[4] = {-1,0,1,0}; int dy[4] = {0,1,0,-1}; typedef pair<int,int> PII; int d[N][N]; int n,x1,x2,y3,y2; queue<PII> q; int bfs(int x,int y){ memset(d,-1,sizeof(d)); q.push({x,y}); d[x][y] = 0; while(!q.empty()){ auto t = q.front(); q.pop(); for(int i = 0 ; i < 4 ; i++){ int xx = dx[i] + t.first; int yy = dy[i] + t.second; if(xx < 1 || xx > n || yy < 1 || yy > n) continue; if(g[xx][yy]!='0') continue; if(d[xx][yy] >= 0) continue; q.push({xx,yy}); d[xx][yy] = d[t.first][t.second] + 1; if(d[x2][y2]>0) return d[x2][y2]; } } } int main() { cin>>n; for(int i = 1 ; i <= n ;i++){ for(int j = 1; j <= n ; j++){ cin>>g[i][j]; } } scanf("%d %d %d %d",&x1,&y3,&x2,&y2); int res = bfs(x1,y3); cout<<res; }
#include<bits/stdc++.h> using namespace std; int dx[8]={-2,-2,-1,+1,-1,+1,+2,+2}; int dy[8]={-1,1,-2,-2,+2,+2,-1,+1}; const int N = 401; int n,m,x,y; int dist[N][N]; typedef pair<int,int> PII; PII q[N*N]; int head,tail; //数组来模拟队列 void bfs(int x1,int y1){ memset(dist,-1,sizeof(dist)); q[0] = {x1,y1}; //起点入队 dist[x1][y1] = 0; int head = 0,tail = 0; while(head<=tail){ auto t = q[head]; //取出队首的元素 类似 t = q.front() head++; //出队 //类似之前 q.pop() for(int i = 0 ; i < 8 ; i++){ for(int j = 0 ; j < 8 ;j++){ int xx = t.first + dx[i]; int yy = t.second + dy[i]; if( xx < 1 || xx > n || yy < 1 || yy > m) continue; if(dist[xx][yy]!=-1) continue; dist[xx][yy] = dist[t.first][t.second] + 1; q[++tail] = {xx,yy}; } } } } int main() { int x1,y1; //起点 cin>>n>>m>>x1>>y1; bfs(x1,y1); for(int i = 1 ;i <= n ;i++){ for(int j = 1 ;j<=m ;j++){ printf("%-5d",dist[i][j]); } cout<<endl; } }
#include<bits/stdc++.h> using namespace std; int dx[4]={-1,1,0,0}; int dy[4]={0,0,1,-1}; const int N = 520; typedef pair<int,int> PII; PII q[N*N]; int dist[N][N]; int a[N][N],flag[N][N]; int m,n,mid; bool check[N][N]; int stx,sty,tp,ans; //bfs用来判断能否到达路标 bool bfs(int mid){ q[0] = {stx,sty}; check[stx][sty] = true; int now = 1; //统计已经到达的路标数 int head = 0 ,tail = 0; while(head<=tail){ auto t =q[head]; head++; for(int i = 0 ; i < 4 ; i++ ){ int xx = t.first + dx[i]; int yy = t.second + dy[i]; if(check[xx][yy]) continue; if(xx < 1 || xx > m || yy < 1 || yy > n) continue; if(abs(a[xx][yy]-a[t.first][t.second])>mid) continue; q[++tail] = {xx,yy}; check[xx][yy] = true; if(flag[xx][yy] == 1){ now++; if(now == tp){ return true; } } } } return false; } int main() { cin>>m>>n; for(int i = 1 ; i <= m ;i++){ for(int j = 1 ; j <= n ;j++){ cin>>a[i][j]; } } int sign = 1; for(int i = 1 ; i <= m ;i++){ for(int j = 1 ; j <= n ;j++){ cin>>flag[i][j]; if(flag[i][j]==1) tp++; //记录路标数 if(flag[i][j] && sign){ sign = 0; stx = i; sty = j; //记录第一个坐标点 } } } int l = -1,r = 1e9+10; while(l+1<r){ mid=(l+r)/2; //先找到一个可能的值 memset(q,0,sizeof q); memset(check,false,sizeof check); if(bfs(mid)){ //判断这个值能不能使汽车从一个路标到达另一个坐标 //如果能到达,说明这个值偏大,应该考虑将它变小一点 r = mid; }else{ // cout<<"4"; //如果不能到达,说明这个值偏小,应该考虑将它变大一点 l = mid ; } } cout<<r; }
#include<bits/stdc++.h> #define ll long long using namespace std; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; ll n; int main() { cin>>n; queue<ll> q; q.push(n); map<ll,ll> mp; mp[n] = 0; while(!q.empty()){ int c[3][3]; int x,y; int t = q.front(); q.pop(); n = t; if(t==123804765) break; //数列转矩阵 for(int i = 2 ; i >= 0 ; i--){ for(int j = 2 ; j>=0 ; j--){ c[i][j] = n%10; n/=10; if(!c[i][j]) x=i,y=j; } } for(int i=0 ;i<4;i++){ ll ns = 0; int xx = dx[i] + x; int yy = dy[i] + y; if(xx < 0 ||yy < 0||xx > 2 || yy > 2) continue; swap(c[xx][yy],c[x][y]); //矩阵转数列 for(int i = 0 ; i < 3 ;i++){ for(int j = 0 ;j <3 ;j++){ ns = ns*10 +c[i][j]; } } //看map里有没有key值为ns的元素,如果有则返回1,否则返回0 if(!mp.count(ns)){ mp[ns] = mp[t] + 1;//统计到达这个状态的步数 q.push(ns); } swap(c[xx][yy],c[x][y]);//状态还原 } } cout<<mp[123804765]<<endl; }
法一:
- #include <iostream>
- using namespace std;
-
- int f(int x) {
- int n = 0;
- while (x) {
- n++;
- x &= x - 1;
- }
- return n;
- }
- int main() {
- cout << f(26) << endl;
- return 0;
- }
法二:
- #include<bits/stdc++.h>
- using namespace std;
-
- int main()
- {
- int n,cnt;
- cin>>n;
- while(n){
- if(n & 1 == 1){
- cnt++;
- }
- n = n >> 1; //向右移一位
- }
- cout<<cnt;
- }
- int lowbit(int x){
- return x & -x;
- }
#include<bits/stdc++.h> using namespace std; const int N = 100010; int n,q; int arr[N]; bool isBlue1(int num , int x){ if(num < x) return true; else return false; } int binary_search1(int arr[],int len,int x) { int l = -1 ,r = len; while(l + 1 != r){ int mid = (l + r) / 2; if(isBlue1(arr[mid],x)){ l = mid; }else{ r = mid; } } if(arr[r]==x){ return r; }else{ return -1; } } bool isBlue2(int num , int x){ if(num <= x) return true; else return false; } int binary_search2(int arr[],int len,int x) { int l = -1 ,r = len; while(l + 1 != r){ int mid = (l + r) / 2; if(isBlue2(arr[mid],x)){ l = mid; }else{ r = mid; } } if(arr[l]==x){ return l; }else{ return -1; } } int main() { cin>>n>>q; for(int i = 0 ; i < n ; i++ ){ cin>>arr[i]; } while(q--){ int x; cin>>x; int res1 = binary_search1(arr,n,x); int res2 = binary_search2(arr,n,x); cout<<res1<<" "<<res2<<endl; } }
#include<bits/stdc++.h> using namespace std; int n,r,l; bool check(double x){ if(x*x*x <= n){ return true; }else{ return false; } } int main() { cin>>n; double l = -100 ,r = 100; while(r - l > 1e-8){ double mid = ( l + r )/2; if(check(mid)){ l = mid; }else{ r = mid; } } cout<<l; }
#include<bits/stdc++.h> using namespace std; int n,m; const int N = 1000010; int a[N]; int mid; bool IsBlue(int x){ if(a[mid] < x) return true; else return false; } int main() { cin>>n>>m; for(int i = 1 ; i <= n ;i++){ cin>>a[i]; } while(m--){ int l = 0 , r = n + 1; int x; cin>>x; while(l + 1 < r){ mid = (l+r)/2 ;//7 if(IsBlue(x)){ l = mid; }else{ r = mid; } } if(a[r]==x){ cout<<r<<" "; }else{ cout<<"-1"<<" "; } } }
#include<iostream> #include<cstdio> #include<cmath> #include<map> #include<algorithm> using namespace std; int n,c; long long ans; map<int,int> a; int num[200005]; int main() { scanf("%d%d",&n,&c); for(int i=1;i<=n;i++) { scanf("%d",&num[i]); a[num[i]]++; //当前数的个数++ } for(int i=1;i<=n;i++) { ans+=a[num[i]+c]; //答案+=相差为c的数的个数,即a[num[i]+c]位置的数的个数 } printf("%lld",ans); return 0; }
A = B + C
枚举 B ,从数组中找 A 的位置
#include<bits/stdc++.h> using namespace std; int n,c; const int N = 1e6; int a[N]; long long mid,cnt; bool IsBlue1(int x){ if(a[mid] < x) return true; else return false; } int search1(int a[],int n ,int x){ int l = -1 ,r = n; while( l + 1 < r){ mid = (l+r)/2; if(IsBlue1(x)){ l = mid; }else{ r = mid; } } if(a[r]==x) return r; else return -1; } // 0 1 1 1 2 3 bool IsBlue2(int x){ if(a[mid] <= x) return true; else return false; } int search2(int a[],int n ,int x){ int l = -1 ,r = n; while( l + 1 < r){ mid = (l+r)/2; if(IsBlue2(x)){ l = mid; }else{ r = mid; } } if(a[l]==x) return l; else return -1; } int main() { cin>>n>>c; for(int i = 0 ; i < n ;i++ ){ cin>>a[i]; } sort(a,a+n); for(int i=0 ; i<n ; i++){ int A = a[i] + c; int res1 = search1(a,n,A); //找左边界 if(res1 == -1) continue; else{ int res2 = search2(a,n,A); //找右边界 cnt += res2 - res1 + 1; } } cout<<cnt; }
首先我们想的会是暴力解法,即从最低端,到最高端进行递增枚举,直到符合要求为止。
其实这样必定会超时的,通过(递增枚举找答案)我们其实是可以想到要用到二分法来做的
找到蓝色最右边那个
#include<bits/stdc++.h> using namespace std; int n,m; const int N = 1000010; int a[N]; bool check(int x){ long long ans = 0; for(int i = 1 ; i <= n ;i++){ ans+=max(0,a[i]-x); } if(ans >= m) return true; else return false; } int main() { cin>>n>>m; int highest = 0; for(int i = 1 ; i <= n ;i++){ cin>>a[i]; highest = max(a[i],highest); } int l = 0, r = highest; while(l + 1 < r){ int mid = (l + r)/2; if(check(mid)){ l = mid; }else{ r = mid; } } cout<<l; }
#include<bits/stdc++.h> #define long long int using namespace std; int n,k; const int N = 100010; int a[N]; bool check(int x) { int ans = 0; for(int i = 0 ; i < n ;i++){ ans +=a[i]/x; if(ans >= k) return true; } return false; } int main() { cin>>n>>k; int longest = 0; for(int i = 0 ; i < n ;i++){ cin>>a[i]; longest = max(a[i],longest); } int r = longest; int l = -1; while(l + 1 < r){ int mid=(r+l)/2; if(check(mid)){ l = mid; }else{ r = mid; } } if(check(r)) cout<<r; else cout<<l; }
由上图所示:所以先 r = mid,再 l = mid;
#include<bits/stdc++.h> using namespace std; const int N = 100010; int a[N]; int s[N]; //表示差值 int n,k,L; bool check(int x){//42 int cnt = 0; //接下来主要是来计算最少需要几个路标 for(int i = 1 ;i <= n + 1 ; i++){ if(s[i] > x){ cnt++; int num = s[i] - x; while(num > x){ cnt++; num-=x; } } } if(cnt<=k) return true; else return false; } int main() { cin>>L>>n>>k; int maxLength; for(int i = 1 ; i <= n ; i++){ cin>>a[i]; s[i] = a[i] - a[i-1]; maxLength = max(maxLength,a[i]); } a[n+1] = L; s[n+1] = a[n+1] - a[n]; int l = 0 , r = maxLength; //直接判断这个答案对不对 //check主要是通过对最少需要的路标数来判断 while(l + 1 < r){ int mid = (l + r) / 2; if(check(mid)){ r = mid; }else{ l =mid; } } if(check(l)) cout<<l; else cout<<r; }
#include<bits/stdc++.h> using namespace std; int L,n,m; const int N = 50010; int a[N]; int s[N]; int mid; bool check(int x){ int cnt = 0,now = 0,i = 0; while(i < n + 1 ){ i++; if(a[i] - a[now] < x){ cnt++; }else{ now = i; } } if(cnt <= m) return true; else return false; } int main() { cin>>L>>n>>m; a[0] = 0; for(int i = 1 ; i <= n ;i++){ cin>>a[i]; } a[n+1] = L; int l = 0 , r = L + 1; while (l + 1 < r){ mid = ( l + r ) / 2; if(check(mid)){ l = mid; }else{ r = mid; } } if(check(r)) cout<<r; else cout<<l; }
#include<bits/stdc++.h> using namespace std; const int N = 100010; int a[N]; bool check(int left , int right) { for(int i= left ; i <= right ; i++ ){ for(int j = i ; j <= right ; j++){ if(i!=j && a[i]==a[j]){ return false; } } } return true; } int main() { cin>>n; for(int i = 1 ; i <= n ;i++){ cin>a[i]; } int res = 0; for(int i = 1 ; i <= n ; i++){ for(int j = i ; j <= n ; j++){ if(check(i,j)){ res = max(res,j - i + 1); } } } cout<<res; }
2.
(从上向底)
- #include<bits/stdc++.h>
- using namespace std;
- int dfs(int x)
- {
- if(x == 1) return 1;
- else if(x == 2) return 2;
- else return dfs(x-1)+dfs(x-2);
- }
- int main()
- {
- int n;
- cin>>n;
- int res = dfs(n);
- cout<<res;
- }
优化:记忆化,避免重复计算
#include<bits/stdc++.h> using namespace std; int msm[20]; int dfs(int x) { int sum = 0; if(x == 1) sum = 1; else if(x == 2) sum = 2; else sum = dfs(x-1)+dfs(x-2); mem[x] = sum; return sum; } int main() { int n; cin>>n; int res = dfs(n); cout<<res; }
法二:(从底向上)
- int f[20];
- int main()
- {
- int n;
- cin>>n;
- f[1]=1,f[2] = 2;
- for(int i = 3 ; i <= n;i++){
- f[i] = f[i-1] + f[i-2];
- }
- cout<<f[n];
- }
#include<bits/stdc++.h> using namespace std; int f[20]={0}; int a[20]; int n; int res = 0; int maxSum = 0; //x 表示当前正在考虑那家店 void dfs(int x) { if(x > n) return 0; else return max(dfs(x+1),dfs(x+2)+a[x]); } int main() { int t; cin>>t; while(t--){ cin>>n; for(int i = 1 ; i <= n ;i++){ cin>>a[i]; } dfs(1); cout<<res<<endl; } }
记忆化搜索进行剪枝:
#include<bits/stdc++.h> using namespace std; int mem[20]; int a[20]; int n; //x 表示当前正在考虑那家店 void dfs(int x) { if(mem[x]) return mem[x]; int sum = 0; if(x > n) sum = 0; else sum = max(dfs(x+1),dfs(x+2)+a[x]); mem[x] = sum; return sum; } int main() { int t; cin>>t; while(t--){ cin>>n; for(int i = 1 ; i <= n ;i++){ cin>>a[i]; } dfs(1); cout<<res<<endl; } }
#include<bits/stdc++.h> using namespace std; int dfs(int x1,int y1) { if(x1 > n || y1 > n) return 0; //求 最优子问题 dfs(x) = max(dfs( x + 1 ),dfs( x + 2)) //求 子问题的和 dfs(x) = dfs( x + 1 ) + dfs( x + 2 ) else return max(dfs (x1 + 1,y1),dfs(x1 + 1,y1 + 1)) + g[x1][y1]; } int main() { cin>>n; for(int i = 1 ; i <= n ;i++){ for(int j = 1 ; j <= i ;j++){ cin>>g[i][j]; } } int res = dfs(1,1); cout<<res; return 0; }
记忆化搜索 优化:
#include<bits/stdc++.h> using namespace std; const int N = 1010; int mem[N][N]; int n; int g[N][N]; int dfs(int x1,int y1) { if(mem[x1][y1]) return mem[x1][y1]; int sum = 0; if(x1 > n || y1 > n) sum = 0; else sum = max(dfs (x1 + 1,y1),dfs(x1 + 1,y1 + 1)) + g[x1][y1]; mem[x1][y1] = sum; return sum; } int main() { cin>>n; for(int i = 1 ; i <= n ;i++){ for(int j = 1 ; j <= i ;j++){ cin>>g[i][j]; } } int res = dfs(1,1); cout<<res; return 0; }
从上往下递归:
#include<bits/stdc++.h> using namespace std; int n; const int N = 1010; int g[N][N],f[N][N]; int main() { cin>>n; for(int i = 1 ; i <= n ;i++){ for(int j = 1 ; j <= i ;j++){ cin>>g[i][j]; } } for(int i = 1 ;i <= n ;i++){ for(int j = 1 ; j <= i ; j++){ f[i][j] = max(f[i-1][j],f[i-1][j-1]) + g[i][j]; } } int res = 0; // 从上往下推,每一个都可能是终点 ,需要遍历找到最大的那个点 for(int i = 1 ; i <= n ;i++){ res = max( res , f[n][i]); } cout<<res; }
python处理大数据不会溢出,自带高精度
(106条消息) 蓝桥杯真题 购物单 EXCEl解法详细步骤_蓝桥杯excel__scling的博客-CSDN博客
(106条消息) [蓝桥杯]Excel题_蓝桥杯excel_天赐细莲的博客-CSDN博客
(106条消息) 【蓝桥杯小技巧】暴力+ Excel的使用(持续更新)_蓝桥杯可以用excel吗_404name的博客-CSDN博客(那个函数与OR相对用AND)
//209.长度最小的数组 #include<bits/stdc++.h> using namespace std; int nums[6]={2,3,1,2,4,3}; int s = 7; int main() { int result = 0x7fffffff; int sum = 0; //滑动窗口数值之和 int i = 0; //滑动窗口起始位置 int subLength = 0; //滑动窗口的长度 for(int j = 0 ; j < 6 ; j++){ sum += nums[j]; while(sum >= s){ subLength = j-i+1; if(result >= subLength){ result = subLength; } sum -= nums[i++]; //精髓之处 } } if(result == 0x7fffffff){ cout<<"0"; }else{ cout<<result; } }
//209.长度最小的数组 #include<bits/stdc++.h> using namespace std; int nums[11]={3,3,3,1,2,1,1,2,3,3,4}; unordered_map<int, int> basket; int main() { int ans = 0; int i = 0; //滑动窗口起始位置 int cnt = 0; // 不断后移终止指针 for(int j = 0 ; j < 11 ; j++){ // 更新cnt if(basket[nums[j]]==0){ cnt++; } basket[nums[j]]++; // 不满足cnt≤2则保守地后移起始指针,一旦满足条件就停止移动 while(cnt>2){ basket[nums[i]]--; if(basket[nums[i]]==0) cnt--; i++; } ans=max(ans,j-i+1); } cout<<ans; }
#include<bits/stdc++.h> using namespace std; unordered_map<char,int> need,win; int main() { string s="ADOBECODEBANC"; string t="ABC"; for(int i = 0 ; i < t.size() ; i++) { need[t[i]]++; } int left = 0,right = 0,start = 0; int cnt = 0; int min_len = 0x7fffffff; //对窗口进行处理 for( right = 0 ; right<s.size() ; right++){ if(need[s[right]] > 0) cnt++; need[s[right]]--; while(cnt == t.size()) { if(min_len > right-left+1) { min_len = right-left + 1; start = left; //方便后续提取子串 } if(need[s[left]]==0) cnt--; need[s[left]]++; left++; } } cout<<s.substr(start,min_len); }
class Solution { public: bool isAnagram(string s, string t) { int record[26] = {0}; for (int i = 0; i < s.size(); i++) { // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了 record[s[i] - 'a']++; } for (int i = 0; i < t.size(); i++) { record[t[i] - 'a']--; } for (int i = 0; i < 26; i++) { if (record[i] != 0) { // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。 return false; } } // record数组所有元素都为零0,说明字符串s和t是字母异位词 return true; } };
#include<bits/stdc++.h> using namespace std; int main() { unordered_set<int> result; // 存放结果,之所以用set是为了给结果集去重 unordered_set<int> nums_set; vector<int> nums1; int nums2[5]; int n,m,a; cin>>n; for(int i = 0 ; i < n ;i++){ cin>>a; nums_set.insert(a); //set用.insert来进行插入 } cin>>m; for(int i = 0 ; i < m ;i++){ cin>>nums2[i]; } for(int i = 0 ; i < m ; i++) { // 发现nums2的元素 在nums_set里又出现过 if(nums_set.find(nums2[i])!=nums_set.end()){ result.insert(nums2[i]); } } for(auto it = result.begin() ; it != result.end() ; it++){ cout<<*it<<" "; //学会输出 } }
#include<bits/stdc++.h> using namespace std; int main() { int nums1[5] = {4,9,5,4,4}; int nums2[6] = {9,4,9,8,4,6}; unordered_map<int,int> mp; for(int i= 0 ; i < 5 ;i++ ){ mp[nums1[i]]++; } int result[6]; int len = 0; for(int i = 0 ; i < 6 ;i++){ if(mp[nums2[i]]!=0){ result[len++] = nums2[i]; mp[nums2[i]]--; } } for(int i = 0 ; i<len ;i++){ cout<<result[i]; } }
#include<bits/stdc++.h> using namespace std; int getSum(int n) { int sum = 0; while(n) { sum+=(n%10)*(n%10); n/=10; } return sum; } int main() { int n; cin>>n; unordered_map<int,int> mp; while(1) { int sum = getSum(n); mp[sum]++; if(sum==1){ cout<<"true"; break; } if(mp[sum]==2){ cout<<"false"; break; } n=sum; } }
#include<bits/stdc++.h> using namespace std; int main() { int target = 26; int nums[4]={2,7,11,15}; unordered_map<int ,int> map; vector<int> v; for(int i = 0 ; i < 4 ;i++){ //遍历当前元素,并在 map 寻找是否有匹配的 key auto iter = map.find(target-nums[i]); if(iter!=map.end()){ v.push_back(i); v.push_back(iter->second); } map.insert(pair<int,int>(nums[i],i)); } for(auto it = v.begin() ; it!=v.end() ; it++){ cout<<*it<<" "; } }
#include<bits/stdc++.h> using namespace std; int main() { int A[2] = {1,2} , B[2] = {-2,-1} ,C[2] = {-1,2} , D[2] = {1,-2}; int sum1[4],len1=0; for(int i = 0 ; i < 2 ;i++){ for(int j = 0 ; j<2 ;j++){ sum1[len1++] = A[i]+B[j]; } } int len2 = 0 ,sum2[4]; for(int i = 0 ; i < 2 ;i++){ for(int j = 0 ; j<2 ;j++){ sum2[len2++] = C[i]+D[j]; } } unordered_map<int,int> mp; int cnt=0; for(int i = 0 ; i < len2 ; i++){ mp[sum2[i]]++; } for(int i = 0; i < len1 ; i++){ if(mp.find(0-sum1[i]) != mp.end()){ cnt+=mp[-sum1[i]]; } } cout<<cnt; }
#include<bits/stdc++.h> using namespace std; int main() { unordered_map<char,int> map; string s1 = "aa"; string s2 = "ava"; for(int i = 0 ; i < s2.size() ; i++){ map[s2[i]]++; } for(int i = 0 ; i < s1.size() ; i++){ map[s1[i]]--; if(map[s1[i]] < 0){ cout<<"false"; return 0; } } cout<<"true"; }
#include<bits/stdc++.h> using namespace std; int main() { vector<vector<int> > result; int nums[6] = {-4,-1,-1,0,1,2}; for(int i = 0 ; i < 6 ; i++){ if(nums[i] > 0){ break; } if(i > 0 && nums[i] == nums[i-1]){ continue; } int left = i + 1; int right = 5; while(left < right){ if(nums[i] + nums[left] + nums[right] > 0) right--; else if(nums[i] + nums[left] + nums[right] < 0) left--; else{ result.push_back(vector<int>{nums[i],nums[left],nums[right]}); //去重操作 while(nums[right] == nums[right-1]) right--; while(nums[left] == nums[left+1]) left++; } left++; right--; } } for(int i = 0 ; i < result.size() ;i++){ vector<int> cmp = result[i]; for(int j = 0 ; j < cmp.size() ; j++){ cout<<cmp[j]<<" "; } cout<<endl; } }
#include<bits/stdc++.h> using namespace std; int main() { int nums[6] = {1,0,-1,0,-2,2}; int target; cin>>target; vector<vector<int> > result; sort(nums,nums+6); for(int k = 0 ; k < 6 ;k++ ){ if(nums[k] > target && nums[k] >= 0 ){ break; } if(k > 0 && nums[k] == nums[k-1]){ continue; } for(int i = k+1 ; i < 6 ; i++){ if(nums[k] + nums[i] > target&&nums[k]+nums[i]>=0 ){ break; } if(i > k+1 && nums[i] == nums[i-1]){ continue; } //和三个数之和操作一样 int left = i+1; int right = 5; while(left < right){ if((long)nums[k] + nums[i] + nums[left] + nums[right] > target){ right--; } else if((long)nums[k] + nums[i] + nums[left] + nums[right] < target){ left++; } else{ result.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]}); while(nums[right] == nums[right-1] && left < right) right--; while(nums[left] == nums[left+1] && left < right) left++; right--; left++; } } } } for(int i = 0 ; i < result.size() ;i++){ vector<int> cmp = result[i]; for(int j = 0 ; j < cmp.size() ; j++){ cout<<cmp[j]<<" "; } cout<<endl; } }
#include<bits/stdc++.h> using namespace std; int main() { unordered_map<int , string> record; int maxmum = INT_MAX; string st; string s; getline(cin,s); //输入带空格字符串 for(int i = 0 ; i < s.size() ;i++){ if(s[i]!=' '){ st+=s[i]; } if(s[i]!=' ' && s[i+1]==' ' && i < s.size() - 1) { st+=' '; record.insert(pair<int,string>(maxmum - i ,st)); st.clear(); } if(s[i]!=' '&&i==s.size()-1){ st+=' '; record.insert(pair<int,string>(maxmum - i ,st)); st.clear(); } } string res; for(auto it = record.begin() ; it!=record.end() ; it++){ res+=it->second; } res.erase(res.end()-1); //删除最后的空格 cout<<res; }
注意反转的方法以及循环 i += 2*k
#include<bits/stdc++.h> using namespace std; int main() { string s = "abcdefg"; int k = 2; for(int i = 0 ; i < s.size() ;i+=2*k ){ // 1. 每隔 2k 个字符的前 k 个字符进行反转 // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符 if(i + k <= s.size()){ reverse(s.begin() + i , s.begin() + i + k); }else{ // 3. 剩余字符少于 k 个,则将剩余字符全部反转 reverse(s.begin() + i , s.end()); } } cout<<s; }
#include<bits/stdc++.h> using namespace std; int main() { queue<char> q; string s; cin>>s; for(int i = 0 ; i < s.size() ; i++){ q.push(s[i]); } int n; cin>>n; while(n--){ char a; a = q.front(); q.push(a); q.pop(); } for(int i = 0 ; i<s.size(); i++){ cout<<q.front(); q.pop(); } }
#include<bits/stdc++.h> using namespace std; int main() { string s; cin>>s; stack<int> st; for(int i = 0 ; i < s.size() ;i++){ if(s[i]=='('){ st.push(')'); } else if(s[i]=='{'){ st.push('}'); } else if(s[i]=='['){ st.push(']'); } else if(st.empty() || st.top() != s[i]){ cout<<"false"; break; }else if(st.top()==s[i]){ st.pop(); } } cout<<"true"; }
//???????????????????????????????????????????????????? #include<bits/stdc++.h> using namespace std; int main() { stack<char> st; string s; cin>>s; for(int i = 0 ; i < s.size() ; i++){ if(s[i]!=st.top() || st.empty()){ st.push(s[i]); }else{ st.pop(); } } while(!st.empty()) { cout<<st.top(); st.pop(); } }
- cin>>n;
- for(int i = 0 ; i < n ;i++){
- cin>>nums[i];
- }
- preSum[0] = 0;
- for(int i = 1 ; i <= n ; i++){
- preNum[i] = preNum[i-1] + nums[i-1];
- }
- void sum(int left , int right){
- return preNum[right+1] - preNum[left];
- }
二维前缀:
- int a[10][10];
- for(int i = 1 ; i <= n ;i++){
- for(int j = 1 ; j <= m ;j++){
- // 计算每个矩阵 [ 0 , 0 , i ,j ] 的元素和
- preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + a[i-1][j-1] - preSum[i-1][j-1];
- }
- }
- int sum(int x1 , int y1 ,int x2,int y2){
- return preSum[x2+1][y2+1] - preSum[x2][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
- }
#include<bits/stdc++.h> using namespace std; int main() { int num[105] , diff[105],n,m; cin>>n>>m; for(int i = 1 ; i <= n ;i++){ cin>>num[i]; } for(int i = 1 ; i <=n ;i++){ diff[i] = num[i] - num[i-1]; } //区间修改操作 for(int i = 0 ; i < m ;i++){ int a,b,c; // 起始位, 结束位 , 改变的值 cin>>a>>b>>c; diff[a] += c; diff[b+1] -= c; } for(int i = 1; i <= n ;i++){ num[i] = num[i-1] + diff[i]; } for(int i = 1 ; i<=n ;i++){ cout<<num[i]<<" "; } cout<<endl; }
二维差分
#include<bits/stdc++.h> using namespace std; const int N=1010; int a[N][N],b[N][N];//a[N][N]为原序列 b[N][N]为a[N][N]的差分 int main() { int n,m; cin>>n>>m; //对差分序列进行处理,也就是一维差分中的构建差分数组 while(m--) { int x1,y1,x2,y2,c = 1; cin>>x1>>y1>>x2>>y2; b[x1][y1]+=c; b[x2+1][y1]-=c; b[x1][y2+1]-=c; b[x2+1][y2+1]+=c; } //对差分求前缀和,输出结果 for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { b[i][j]+=b[i][j-1]+b[i-1][j]-b[i-1][j-1]; cout<<b[i][j]<<" "; } cout<<endl; } return 0; }
、
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。