打表-年份日期问题
w= ( d+ 2 * m+ 3 * ( m+ 1 ) / 5 + y+ y/ 4 - y/ 100 + y/ 400 ) % 7 + 1
#include <bits/stdc++.h>
using namespace std;
int months[ 13 ] = { 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
int weeks[ 7 ] ;
int main ( ) {
int n; cin>> n;
int days= 0 ;
for ( int year= 1900 ; year< 1900 + n; year++ ) {
for ( int i= 1 ; i<= 12 ; i++ ) {
weeks[ ( days+ 12 ) % 7 ] ++ ;
days+ = months[ i] ;
if ( i== 2 ) {
if ( year% 100 != 0 && year% 4 == 0 || year% 400 == 0 ) {
days++ ;
}
}
}
}
for ( int i= 5 , j= 1 ; j<= 7 ; j++ , i= ( i+ 1 ) % 7 )
cout<< weeks[ i] << " " ;
return 0 ;
}
多关键字比较
重载<
#include <bits/stdc++.h>
using namespace std;
const int N= 310 ;
struct Person{
int id, sum, a, b, c;
bool operator < ( const Person t) const {
if ( sum!= t. sum) return sum> t. sum;
if ( a!= t. a) return a> t. a;
else return id< t. id;
}
} q[ N] ;
int main ( ) {
int n; cin>> n;
for ( int i= 1 ; i<= n; i++ ) {
int a, b, c;
cin>> a>> b>> c;
q[ i] = { i, a+ b+ c, a, b, c} ;
}
sort ( q+ 1 , q+ 1 + n) ;
for ( int i= 1 ; i<= 5 ; i++ ) {
cout<< q[ i] . id<< " " << q[ i] . sum<< endl;
}
return 0 ;
}
自定义cmp函数
#include <bits/stdc++.h>
using namespace std;
const int N= 310 ;
struct Person
{
int id, sum, a, b, c;
} q[ N] ;
bool cmp ( Person a, Person b) {
if ( a. sum!= b. sum) return a. sum> b. sum;
if ( a. a!= b. a) return a. a> b. a;
else return a. id< b. id;
}
int main ( ) {
int n; cin>> n;
for ( int i= 1 ; i<= n; i++ ) {
int a, b, c;
cin>> a>> b>> c;
q[ i] = { i, a+ b+ c, a, b, c} ;
}
sort ( q+ 1 , q+ 1 + n, cmp) ;
for ( int i= 1 ; i<= 5 ; i++ ) {
cout<< q[ i] . id<< " " << q[ i] . sum<< endl;
}
return 0 ;
}
快速排序
#include <bits/stdc++.h>
using namespace std;
const int N= 1e6 + 10 ;
int n;
int q[ N] ;
void quick_sort ( int q[ ] , int l, int r) {
if ( l>= r) return ;
int x= q[ l+ r >> 1 ] , i= l- 1 , j= r+ 1 ;
while ( i< j) {
do i++ ; while ( q[ i] < x) ;
do j-- ; while ( q[ j] > x) ;
if ( i< j) swap ( q[ i] , q[ j] ) ;
}
quick_sort ( q, l, j) ;
quick_sort ( q, j+ 1 , r) ;
}
int main ( ) {
cin>> n;
for ( int i= 0 ; i< n; i++ ) scanf ( "%d" , & q[ i] ) ;
quick_sort ( q, 0 , n- 1 ) ;
for ( int i= 0 ; i< n; i++ ) cout<< q[ i] << " " ;
return 0 ;
}
归并排序
#include <bits/stdc++.h>
using namespace std;
const int N= 1e6 + 10 ;
int n;
int q[ N] ;
int tmp[ N] ;
void merge_sort ( int q[ ] , int l, int r) {
if ( l>= r) return ;
int mid= l + r >> 1 ;
merge_sort ( q, l, mid) ;
merge_sort ( q, mid+ 1 , r) ;
int i= l, k= 0 , j= mid+ 1 ;
while ( i<= mid&& j<= r) {
if ( q[ i] <= q[ j] ) tmp[ k++ ] = q[ i++ ] ;
else tmp[ k++ ] = q[ j++ ] ;
}
while ( i<= mid) tmp[ k++ ] = q[ i++ ] ;
while ( j<= r) tmp[ k++ ] = q[ j++ ] ;
for ( i= l, k= 0 ; i<= r; i++ , k++ ) q[ i] = tmp[ k] ;
}
int main ( ) {
cin>> n;
for ( int i= 0 ; i< n; i++ ) scanf ( "%d" , & q[ i] ) ;
merge_sort ( q, 0 , n- 1 ) ;
for ( int i= 0 ; i< n; i++ ) printf ( "%d " , q[ i] ) ;
return 0 ;
}
二分查找
整数二分
#include <bits/stdc++.h>
using namespace std;
int q[ 100100 ] ;
int l, r;
int search_right ( int l, int r, int x) {
while ( l< r) {
int mid= ( l + r ) >> 1 ;
if ( q[ mid] >= x) r= mid;
else l= mid+ 1 ;
}
return l;
}
int search_left ( int l, int r, int x) {
while ( l< r) {
int mid= ( l + r + 1 ) >> 1 ;
if ( q[ mid] <= x) l= mid;
else r= mid- 1 ;
}
return l;
}
int main ( ) {
int n, m; cin>> n>> m;
for ( int i= 0 ; i< n; i++ ) cin>> q[ i] ;
while ( m-- ) {
int x; cin>> x;
l= 0 , r= n- 1 ;
int l1= search_right ( l, r, x) ;
if ( q[ l1] != x)
{
cout<< "-1 -1" << endl;
continue ;
}
else
{
cout<< l1<< " " ;
}
l= 0 , r= n- 1 ;
int l2= search_left ( l, r, x) ;
cout<< l2<< endl;
}
return 0 ;
}
lower_bound,upper_bound
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。upper_bound最后结果可能要减1
#include <bits/stdc++.h>
using namespace std;
const int N= 100010 ;
int a[ N] ;
int n, q;
int main ( ) {
cin>> n>> q;
for ( int i= 0 ; i< n; i++ ) scanf ( "%d" , & a[ i] ) ;
while ( q-- ) {
int t; cin>> t;
int x= lower_bound ( a, a+ n, t) - a;
int y= upper_bound ( a, a+ n, t) - a;
if ( a[ -- y] == t) cout<< x<< " " << y<< endl;
else cout<< - 1 << " " << - 1 << endl;
}
return 0 ;
}
浮点二分
#include <bits/stdc++.h>
using namespace std;
const int N= 100010 ;
int n, m;
int q[ N] ;
bool check ( double mid) {
int cnt= 0 ;
for ( int i= 0 ; i< n; i++ ) {
cnt+ = q[ i] / mid;
}
if ( cnt>= m) return true ;
else return false ;
}
int main ( ) {
cin>> n>> m;
for ( int i= 0 ; i< n; i++ ) cin>> q[ i] ;
sort ( q, q+ n) ;
double l= 0 , r= q[ n- 1 ] ;
while ( r- l> 1e-4 ) {
double mid= ( l+ r) / 2 ;
if ( check ( mid) ) l= mid;
else r= mid;
}
printf ( "%.2lf\n" , r) ;
return 0 ;
}
进制转换 、回文数、字母和数字转换
#include <bits/stdc++.h>
using namespace std;
char get ( int n) {
if ( n<= 9 ) return n+ '0' ;
return n- 10 + 'A' ;
}
string base ( int n, int b) {
string num;
while ( n) {
num+ = get ( n% b) ;
n/ = b;
}
reverse ( num. begin ( ) , num. end ( ) ) ;
return num;
}
bool check ( string num) {
for ( int i= 0 , j= num. size ( ) - 1 ; i< j; i++ , j-- ) {
if ( num[ i] != num[ j] ) {
return false ;
}
}
return true ;
}
int main ( ) {
int b; cin>> b;
for ( int i= 1 ; i<= 300 ; i++ ) {
string num= base ( i* i, b) ;
if ( check ( num) ) {
cout<< base ( i, b) << " " << num<< endl;
}
}
return 0 ;
}
其他进制转换成10进制
int uget ( char c) {
if ( c<= '9' ) return c- '0' ;
return c- 'A' + 10 ;
}
int base10 ( string num, int b) {
int res= 0 ;
for ( int i= 0 ; i<= num. size ( ) - 1 ; i++ ) {
char c= num[ i] ;
res= res* b+ uget ( c) ;
}
return res;
}
高精度:
加法
#include <bits/stdc++.h>
using namespace std;
vector< int > add ( vector< int > & A, vector< int > & B) {
vector< int > C;
int t= 0 ;
for ( int i= 0 ; i< A. size ( ) || i< B. size ( ) ; i++ ) {
if ( i< A. size ( ) ) t+ = A[ i] ;
if ( i< B. size ( ) ) t+ = B[ i] ;
C. push_back ( t% 10 ) ;
t/ = 10 ;
}
if ( t) C. push_back ( 1 ) ;
return C;
}
int main ( ) {
string a, b;
vector< int > A, B;
cin>> a>> b;
for ( int i= a. size ( ) - 1 ; i>= 0 ; i-- ) A. push_back ( a[ i] - '0' ) ;
for ( int i= b. size ( ) - 1 ; i>= 0 ; i-- ) B. push_back ( b[ i] - '0' ) ;
vector< int > C= add ( A, B) ;
for ( int i= C. size ( ) - 1 ; i>= 0 ; i-- ) cout<< C[ i] ;
return 0 ;
}
减法
乘法
vector< int > mul ( vector< int > & A, int b)
{
vector< int > C;
int t = 0 ;
for ( int i = 0 ; i < A. size ( ) || t; i ++ )
{
if ( i < A. size ( ) ) t + = A[ i] * b;
C. push_back ( t % 10 ) ;
t / = 10 ;
}
while ( C. size ( ) > 1 && C. back ( ) == 0 ) C. pop_back ( ) ;
return C;
}
除法
前缀和
一维
#include <bits/stdc++.h>
using namespace std;
const int N= 100010 ;
int n, m;
int a[ N] , s[ N] ;
int main ( ) {
ios:: sync_with_stdio ( false ) ;
cin>> n>> m;
for ( int i= 1 ; i<= n; i++ ) cin>> a[ i] ;
for ( int i= 1 ; i<= n; i++ ) s[ i] = s[ i- 1 ] + a[ i] ;
while ( m-- ) {
int l, r;
cin>> l>> r;
cout<< s[ r] - s[ l- 1 ] << endl;
}
return 0 ;
}
二维
#include <bits/stdc++.h>
using namespace std;
const int N= 1010 ;
int n, m, q;
int a[ N] [ N] , s[ N] [ N] ;
int main ( ) {
ios:: sync_with_stdio ( false ) ;
cin>> n>> m>> q;
for ( int i= 1 ; i<= n; i++ )
for ( int j= 1 ; j<= m; j++ )
cin>> a[ i] [ j] ;
for ( int i= 1 ; i<= n; i++ )
for ( int j= 1 ; j<= m; j++ )
s[ i] [ j] = s[ i- 1 ] [ j] + s[ i] [ j- 1 ] - s[ i- 1 ] [ j- 1 ] + a[ i] [ j] ;
while ( q-- ) {
int x1, y1, x2, y2;
cin>> x1>> y1>> x2>> y2;
cout<< s[ x2] [ y2] - s[ x2] [ y1- 1 ] - s[ x1- 1 ] [ y2] + s[ x1- 1 ] [ y1- 1 ] << endl;
}
return 0 ;
}
差分
一维
#include <bits/stdc++.h>
using namespace std;
const int N= 100100 ;
int n, m;
int a[ N] , b[ N] ;
void insert ( int l, int r, int c) {
b[ l] + = c;
b[ r+ 1 ] - = c;
}
int main ( ) {
ios:: sync_with_stdio ( false ) ;
cin>> n>> m;
for ( int i= 1 ; i<= n; i++ ) cin>> a[ i] ;
for ( int i= 1 ; i<= n; i++ ) insert ( i, i, a[ i] ) ;
while ( m-- ) {
int l, r, c;
cin>> l>> r>> c;
insert ( l, r, c) ;
}
for ( int i= 1 ; i<= n; i++ ) b[ i] + = b[ i- 1 ] ;
for ( int i= 1 ; i<= n; i++ ) cout<< b[ i] << ””;
return 0 ;
}
二维
#include <bits/stdc++.h>
using namespace std;
const int N= 1010 ;
int n, m, q;
int b[ N] [ N] , a[ N] [ N] ;
void insert ( int x1, int y1, int x2, int y2, int c) {
b[ x1] [ y1] + = c;
b[ x2+ 1 ] [ y1] - = c;
b[ x1] [ y2+ 1 ] - = c;
b[ x2+ 1 ] [ y2+ 1 ] + = c;
}
int main ( ) {
ios:: sync_with_stdio ( false ) ;
cin>> n>> m>> q;
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 1 ; j<= m; j++ ) {
cin>> a[ i] [ j] ;
insert ( i, j, i, j, a[ i] [ j] ) ;
}
}
while ( q-- ) {
int x1, y1, x2, y2, c;
cin>> x1>> y1>> x2>> y2>> c;
insert ( x1, y1, x2, y2, c) ;
}
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 1 ; j<= m; j++ ) {
b[ i] [ j] + = b[ i- 1 ] [ j] + b[ i] [ j- 1 ] - b[ i- 1 ] [ j- 1 ] ;
}
}
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 1 ; j<= m; j++ ) {
cout<< b[ i] [ j] << " " ;
}
cout<< endl;
}
return 0 ;
}
双指针
for ( i= 0 ; j= 0 ; i< n; i++ ) {
while ( j< i&& check ( i, j) ) j++ ;
}
#include <bits/stdc++.h>
using namespace std;
int main ( ) {
char str[ 1000 ] ;
gets ( str) ;
int n= strlen ( str) ;
for ( int i= 0 ; i< n; i++ ) {
int j= i;
while ( j< n&& str[ j] != ' ' ) j++ ;
for ( int k= i; k< j; k++ ) cout<< str[ k] ;
cout<< endl;
i= j;
}
return 0 ;
}
#include <bits/stdc++.h>
using namespace std;
const int N= 100100 ;
int a[ N] , s[ N] ;
int n;
int main ( ) {
cin>> n;
int res= 0 ;
for ( int i= 0 ; i< n; i++ ) cin>> a[ i] ;
for ( int i= 0 , j= 0 ; i< n; i++ ) {
s[ a[ i] ] ++ ;
while ( s[ a[ i] ] > 1 ) {
s[ a[ j] ] -- ;
j++ ;
}
res= max ( res, i- j+ 1 ) ;
}
cout<< res<< endl;
return 0 ;
}
位运算
n的二进制第 k位表示是几
#include <bits/stdc++.h>
using namespace std;
int main ( ) {
int n= 10 ;
for ( int k= 3 ; k>= 0 ; k-- ) cout<< ( n>> k & 1 ) ;
return 0 ;
}
统计二进制1的个数
#include <bits/stdc++.h>
using namespace std;
int lowbit ( int x) {
return x & - x;
}
int main ( ) {
int n; cin>> n;
while ( n-- ) {
int x; cin>> x;
int res= 0 ;
while ( x) {
x- = lowbit ( x) ;
res++ ;
}
cout<< res<< " " ;
}
return 0 ;
}
离散化
#include <bits/stdc++.h>
using namespace std;
typedef pair< int , int > PII;
const int N= 300010 ;
int n, m;
int a[ N] , s[ N] ;
vector< int > alls;
vector< PII> add, query;
int find ( int x) {
int l= 0 , r= alls. size ( ) - 1 ;
while ( l< r) {
int mid= ( l+ r) >> 1 ;
if ( alls[ mid] >= x) r= mid;
else l= mid+ 1 ;
}
return r+ 1 ;
}
int main ( ) {
cin>> n>> m;
for ( int i= 0 ; i< n; i++ ) {
int x, c;
cin>> x>> c;
add. push_back ( { x, c} ) ;
alls. push_back ( x) ;
}
for ( int i= 0 ; i< m; i++ ) {
int l, r;
cin>> l>> r;
query. push_back ( { l, r} ) ;
alls. push_back ( l) ;
alls. push_back ( r) ;
}
sort ( alls. begin ( ) , alls. end ( ) ) ;
alls. erase ( unique ( alls. begin ( ) , alls. end ( ) ) , alls. end ( ) ) ;
for ( vector< PII> :: iterator item= add. begin ( ) ; item!= add. end ( ) ; item++ ) {
int x= find ( ( * item) . first) ;
a[ x] + = ( * item) . second;
}
for ( int i= 1 ; i<= alls. size ( ) ; i++ ) s[ i] = s[ i- 1 ] + a[ i] ;
for ( vector< PII> :: iterator item= query. begin ( ) ; item!= query. end ( ) ; item++ ) {
int l= find ( ( * item) . first) ;
int r= find ( ( * item) . second) ;
cout<< s[ r] - s[ l- 1 ] << endl;
}
return 0 ;
}
区间合并
#include <bits/stdc++.h>
using namespace std;
typedef pair< int , int > PII;
vector< PII> segs;
void merge ( vector< PII> & segs) {
vector < PII> res;
sort ( segs. begin ( ) , segs. end ( ) ) ;
int st= - 2e9 , ed= - 2e9 ;
for ( int i= 0 ; i< segs. size ( ) ; i++ ) {
if ( ed< segs[ i] . first) {
if ( st!= - 2e9 ) res. push_back ( { st, ed} ) ;
st= segs[ i] . first;
ed= segs[ i] . second;
}
else ed= max ( segs[ i] . second, ed) ;
}
if ( st!= - 2e9 ) res. push_back ( { st, ed} ) ;
segs= res;
}
int main ( ) {
int n; cin>> n;
for ( int i= 0 ; i< n; i++ ) {
int l, r;
cin>> l>> r;
segs. push_back ( { l, r} ) ;
}
merge ( segs) ;
cout<< segs. size ( ) << endl;
return 0 ;
}
#include <bits/stdc++.h>
using namespace std;
const int N= 110 ;
struct Segment{
int l, r;
bool operator < ( const Segment& t) const
{
return l< t. l;
}
} seg[ N] ;
int main ( ) {
int n, m; cin>> m>> n;
for ( int i= 0 ; i< n; i++ ) cin>> seg[ i] . l>> seg[ i] . r;
sort ( seg, seg+ n) ;
int sum= 0 ;
int L= seg[ 0 ] . l, R= seg[ 0 ] . r;
for ( int i= 1 ; i< n; i++ ) {
if ( seg[ i] . l<= R) R= max ( R, seg[ i] . r) ;
else {
sum+ = R- L+ 1 ;
L= seg[ i] . l, R= seg[ i] . r;
}
}
sum+ = R- L+ 1 ;
cout<< m+ 1 - sum<< endl;
return 0 ;
}