RPG难题
/*
先列出前面几项观察下规律, a[1] = 3, a[2] = 6, a[3] = 6;
按照一般的思路,找涂n个方格的方法数,可以看涂n-1个方格的方法数,然后涂第n个方格多了多少种方法
根据题中“要求任何相邻的方格不能同色,且首尾两格也不同色 ”可知
当n大于等于4时,第1格到第n-1格(大于等于3)才不是相邻的
思路来源:涂好了前n-1格的基础上涂第n格,保证第1格和第n格颜色不同,且第n-1格与第n格颜色不同
所以需要去分类讨论第1格和第n-1格的颜色是否相同
所以得到一个讨论的条件:(当n大于等于4时)(总共有3种颜色)
1.第1格与第n-1格同色时,涂第n格可以有2种方法,此时满足第1格与第n格颜色不同,第n-1格与第n格颜色不同
而此时涂前n-1格的方法数实际上只是涂前n-2格的方法数(第1格与第n-1格同色),所以有2*a[n-2]种方法
2.第1格与第n-1格不同色时,涂第n格只能有1种方法,此时满足第1格与第n格颜色不同,第n-1格与第n格颜色不同
而此时涂前n-1格的方法数为a[n-1]
所以涂前n格的方法数为a[n]=a[n-1]+2*a[n-2]
*/
#include <iostream>
using namespace std;
int main(){
long long a[60];//用long long存取,因为当n较大时数会很大,保险起见
int n;
a[1] = 3;
a[2] = 6;
a[3] = 6;
while(cin >> n){
for(int i = 4; i <= n; i++){
a[i] = a[i - 1] + 2*a[i - 2];
}
cout << a[n] << endl;
}
return 0;
}
2049
错排公式:D(n)=(n-1)*(D(n-1)+D(n-2))
#include<stdio.h>
long long swp1(int i);
long long swp2(int a,int b);
int main()
{
long long k;
int c,n,m;
scanf("%d",&c);
for(int l=0;l<c;l++)
{
scanf("%d %d",&n,&m);
k=swp1(m)*swp2(n,m);
printf("%lld\n",k);
}
return 0;
}
long long swp1(int i)
{
if(i==1)
return 0;
else if(i==2)
return 1;
else
return (i-1)*(swp1(i-1)+swp1(i-2));
}
long long swp2(int a,int b)
{
int sum=1;
for(int j=1;j<=b;j++)
sum=(sum*(a-b+j))/j;
return sum;
}
//快速排序
#include <bits/stdc++.h>
using namespace std;
int n;
int arr[1000];
int i,j;
void quick_sort(int arr[], int l, int r)
{
if(l >= r) return;
int x = arr[l + r >> 1];
int i = l - 1, j = r + 1;
while(i < j)
{
do i ++; while(arr[i] < x);
do j --; while(arr[j] > x);
if(i < j) swap(arr[i], arr[j]);
}
quick_sort(arr, l, j);
quick_sort(arr, j + 1, r);
}
int main()
{
cin >> n;
for (int i = 0;i < n;i++)
cin >> arr[i];
quick_sort(arr,0,n-1);
for (int i = 0;i < n;i++)
cout << arr[i];
return 0;
}
2079
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
double h,m,s;
double y1,y2,y3,y4;
scanf("%lf%lf%lf",&h,&m,&s);
if(h>=12)
h=h-12;
y1=s/60;
y2=(m+y1)/60;
y3=y2*360;
y4=(h+y2)*30;
if(y4>y3)
{
if((y4-y3)>180)
printf("%d\n",int (360-y4+y3));
else
printf("%d\n",int (y4-y3));
}
else
{
if((y3-y4)>180)
printf("%d\n",int (360-y3+y4));
else
printf("%d\n",int (y3-y4));
}
}
return 0;
}
1. 序列的长度为 5。
2. 序列中的每个数都是 1 到 10 之间的整数。
3. 序列中后面的数大于等于前面的数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m, res;
int i, j;
char arr[25][25];
int dx[][2] = {0,1,0,-1,1,0,-1,0};
typedef pair<int,int> P;
void dfs(vector<int> path)
{
if(path.size() == 5){
for(int i = 0;i < 5;i ++){
cout<<path[i]<<" ";
}
cout<<endl;
res++;
return;
}
for(int i = 1; i <= 10; i++){
if(path.size() == 0){
path.push_back(i);
dfs(path);
path.pop_back();
} else{
if(i >= path[path.size() -1 ]){
path.push_back(i);
dfs(path);
path.pop_back();
}
}
}
}
int main(void)
{
vector<int> path;
dfs(path);
cout<<res<<endl;
return 0;
}
//2002
两个字母之间的距离定义为它们在字母表中位置的距离。例如 A 和 C 的距离为 2,L 和 Q 的距离为 5。
对于一个字符串,我们称字符串中两两字符之间的距离之和为字符串的内部距离。
例如:ZOO 的内部距离为 22,其中 Z 和 O 的距离为 11。
请问,LANQIAO 的内部距离是多少?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m, res;
int i, j;
char arr[25][25];
int dx[][2] = {0,1,0,-1,1,0,-1,0};
typedef pair<int,int> P;
int main(void)
{
string s = "LANQIAO";
//cout << 'Z' - 'O' <<endl;
int len = s.size();
for(int i = 0; i < len; i++) {
for(int j = i + 1; j < len; j++) {
res += abs(s[i] - s[j]);
}
}
cout<< res <<endl;
return 0;
}
//162
输入的第一行包含两个整数 n, m。
第二行包含一个整数 t,表示出水管的数量。
接下来 t 行描述出水管的位置,其中第 i 行包含两个数 r, c 表示第 r 行第 c 列有一个排水管。
接下来一行包含一个整数 k。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a, b, t, r, c, k;
int m, n, res;
int arr[105][105];
int dx[][2] = {0,1,0,-1,1,0,-1,0};
typedef pair<int,int> P;
map<P,int> mp;
queue<P> que;
int sum[10000];
void bfs(){
while(!que.empty()) {
P tp = que.front();
que.pop();
for(int i = 0; i < 4; i++) {
int xx = tp.first + dx[i][0];
int yy = tp.second + dx[i][1];
if(1 <= xx && xx <= n && 1 <= yy && yy <= m && arr[xx][yy] == 0){
P tmp = make_pair(xx, yy);
arr[xx][yy] = 1;
que.push(tmp);
mp[tmp] = mp[tp] + 1;
sum[mp[tp] + 1] ++;
}
}
}
}
int main(void)
{
scanf("%d %d %d", &n, &m, &t);
for(int i = 0; i < t; i++) {
scanf("%d %d", &r, &c);
arr[r][c] = 1;
P st = make_pair(r,c);
que.push(st);
mp[st] = 0;
sum[0] ++;
}
scanf("%d", &k);
bfs();
for(int i = 0; i <= k; i++)
res += sum[i];
printf("%d\n", res);
return 0;
}
高精度+高精度
vector<int> add(vector<int> A, vector<int> B)
{
if(A.size() < B.size()) return add(B, A);
vector<int> C;
int t = 0;
for(int i = 0; i < A.size(); i++)
{
t += A[i];
if(i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if(t) C.push_back(t);
return C;
}
高精度-高精度
vector<int> sub(vector<int> A, vector<int> B)
{
vector<int> C;
int t = 0;
for(int i = 0; i < A.size(); i++)
{
t += A[i];
if(i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if(t < 0) t = -1;
else t = 0;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
高精度*低精度
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 <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> div(vector<int> A, int b, int &r)
{
vector<int> C;
r = 0;
for(int i = A.size() - 1; i >= 0; i--)
{
r = r * 10 + A[i];
C.push_back(r / b);
r = r % b;
}
reverse(C.begin(), C.end());
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main(void)
{
string a;
int b;
cin >> a >> b;//123456
vector<int> A, C;
for(int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');//654321
int r;
C = div(A, b, r);
for(int i = C.size() - 1; i >= 0; i--) cout << C[i];
cout << endl << r << endl;
return 0;
}
输入的第一行包含两个整数 n, m,表示图的大小。
接下来 n 行,每行 m 个整数,表示方格图中每个点的权值。
#include<bits/stdc++.h>
using namespace std;
int m, n;
int arr[50][50];
int dp[50][50];
int main(void)
{
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &arr[i][j]);
dp[0][0] = arr[0][0];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
for(int k = 1; k <= 3 ; k++){
if(i -k >=0)
dp[i][j] = max(dp[i][j], dp[i - k][j] + arr[i][j]);
if(j - k >=0)
dp[i][j] = max(dp[i][j], dp[i][j - k] + arr[i][j]);
if(i - k >= 0 && j - k >= 0)
dp[i][j] = max(dp[i][j], max(dp[i - k][j] + arr[i][j], dp[i][j - k] + arr[i][j]));
}
}
}
printf("%d\n",dp[n - 1][m - 1]);
return 0;
}
2078
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int u;
int n,m;
int minn;
scanf ("%d",&u);
while (u--)
{
scanf ("%d %d",&n,&m);
minn = 100;
while (n--)
{
int t;
scanf ("%d",&t);
minn = min (minn , t);
}
printf ("%d\n",(100-minn)*(100-minn));
}
return 0;
}
埃式筛法
const int N = 1000010;
int n, primes[N], cnt;
bool st[N];
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i])
{
primes[cnt++] = i;
for(int j = i + i; j <= n; j += i) st[j] = true;
}
}
}
欧拉筛法
const int N = 1000010;
int n, primes[N], cnt;
bool st[N];
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i]) primes[cnt++] = i;
for(int j = 0; primes[j] <= n / i; j++)
{
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;//直到找到i的最小质因子退出循环
}
}
}
快速幂
0 <= a, k, p <= 10^9
int qmi(int a, int k, int p)
{
int res = 1;
while(k)
{
if(k & 1) res = (LL)res * a % p;
k >>= 1;
a = (LL)a * a % p;
}
retrn res;
}
E题
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <sstream>
#include <stack>
using namespace std;
const int N = 55;
int n, a[N];
int main(void)
{
int T;
cin >> T;
while(T--)
{
int l, r;
cin >> n;
for(int i = 0; i < n; i++) cin >> a[i];
bool flag = false;
for(int i = 0; i < n; i++)
{
if(!flag && a[i]) l = i, flag = true;//找到最左边的1
if(a[i]) r = i;//找到最右边的1
}
int res = 0;
for(int i = l; i <= r; i++)
{
if(!a[i]) res++;
}
cout << res << endl;
}
return 0;
}