九进制转十进制
利用进制转换的公式即可
#include
#include
using namespace std;
int year=2022;
int ans=0,a=0;
int main(){
while(year){
res+=(int)pow(9,a)*(year%10);
year/=10;
a++;}
cout<
顺子日期
顺子每两个数之间差一
#include
using namespace std;
int ans = 0;
int month[12] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int day[12] = { 31,29,31,30,31,30,31,31,30,31,30,31 };//打表
int main() {
for (int i = 0; i < 12; i++) {
for (int k = 1; k <= day[i]; k++) {
int a = month[i] % 10 - month[i] / 10;//差值
int b = k / 10 - month[i] % 10;//差值2
int c = k % 10 - k / 10;//差值三
if(a == 1 && b == 1)ans++;
if (c == 1&& b == 1)ans++;
if (a == 1 && b == 1 && c == 1)ans--;
}
}
cout << ans;
return 0;
}
刷题统计
先算整周的倍数,余下的天数直接枚举
#include
using namespace std;
long long n, a, b,ans=0;
int main() {
cin >> a >> b >> n;
long long week = 5 * a + 2 * b;
if (n % week > 0 && n % week <= a)ans += 1;
if (n % week > a && n % week <= a*2)ans += 2;
if (n % week > a*2 && n % week <= a*3)ans += 3;
if (n % week > a*3 && n % week <= a*4)ans += 4;
if (n % week > a*4 && n % week <= a*5)ans += 5;
if (n % week > a*5 && n % week <= a*5+b)ans += 6;
if (n % week > a * 5+b && n % week <= a * 5 + 2*b)ans += 7;//数据不大直接枚举
ans += n / week * 7;
cout << ans;
return 0;
}
修减灌木
找规律罢了
#include
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cout<
x进制减法
找规律,模拟
#include
#include
#include
using namespace std;
const int N=1e5+5,M=1e9+7;
int a[N],b[N];
int main(){
int n,na,nb;
cin>>n;
cin>>na;
for(int i=na;i>0;i--){
scanf("%d",&a[i]);
}
cin>>nb;
for(int i=nb;i>0;i--){
scanf("%d",&b[i]);
}
long long sum=0;
for(int i=na;i>0;i--){
sum=sum*max(2,max(a[i],b[i])+1)%M;
sum=((sum+a[i]-b[i])%M+M)%M;
}
cout<
统计子矩阵
二维数组的前缀和(直接模拟会tle)
#include
#include
using namespace std;
int a[501][501],s[501][501];
long long ans;
int main(){
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
s[i][j]=s[i-1][j]+a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
int sum=0;
for(int l=1,r=1;r<=m;r++){
sum+=s[j][r]-s[i-1][r];
while(sum>k) sum-=(s[j][l]-s[i-1][l]),l++;
ans+=r-l+1;
}
}
}
printf("%lld",ans);
return 0;
}
堆积木
列举出末尾的排列情况,求和即可(l方块可以正反放置,所以要乘2)
#include
const int M=1e9+7;
int F[1000010];
int preF[1000010];
int n;
int main(){
std::cin >> n;
F[0] = 1;
preF[0]=1;
for(int i=1; i<=n; i++){
F[i]=(i-1<0?0:preF[i-1])+(i-3<0?0:preF[i-3]);
F[i] %= M;
preF[i] = preF[i-1]+F[i];
preF[i] %= M;
}
std::cout << F[n] << std::endl;
return 0;
}
扫雷
哈希,dfs
#include
using namespace std;
const int N = 50010, M = 999997;
struct circle {
int x, y, r;
}cir[N];
int id[M];
bool sc[M];
#define ll long long
ll h[M];
ll get_key(int x, int y) {
return x * 1000000001ll + y;
}
int find(int x, int y) {
ll key = get_key(x, y);
int t = (key%M + M) % M;
while (h[t] != -1 && h[t] != key) {
if (++t == M)t = 0;
}
return t;
}
int sqr(int x) {
return x*x;
}
void dfs(int x, int y, int r) {
sc[find(x, y)] = true;
for (int i = x - r; i <= x + r; i++) {
for (int j = y - r; j <= y + r; j++) {
if (sqr(i-x) + sqr(j-y) <= sqr(r)) {
int t = find(i, j);
if (id[t] && !sc[t]) {
dfs(i, j, cir[id[t]].r);
}
}
}
}
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
memset(h, -1, sizeof(h));
for (int i = 1; i <= n; i++) {
int x, y, r;
scanf("%d%d%d", &x, &y, &r);
cir[i] = { x,y,r };
int t = find(x, y);
if (h[t] == -1)h[t] = get_key(x, y);
if (!id[t] || cir[id[t]].r < r)id[t] = i;
}
while (m--) {
int x, y, r;
scanf("%d%d%d", &x, &y, &r);
for (int i = x - r; i <= x + r; i++) {
for (int j = y - r; j <= y + r; j++) {
if (sqr(i-x) + sqr(j-y) <= sqr(r)) {
int t = find(i, j);
if (id[t] && !sc[t]) {
dfs(i, j, cir[id[t]].r);
}
}
}
}
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (sc[find(cir[i].x, cir[i].y)])res++;
}
printf("%d\n", res);
return 0;
}
李白打酒加强版
dp,找规律,最后一次必遇到花
#include
using namespace std;
typedef long long ll;
const int N=220,mod=1e9+7;
ll n,m,ans,len;
ll dp[N][N][N]; //前i次 有j次遇到店 剩下酒为k斗
int main()
{
int t;
cin>>t;
while(t--){
cin>>n>>m; //N店 M花
len=n+m;
memset(&dp[0][0][0],0,sizeof(dp));
dp[0][0][2]=1; //初始有2斗酒
for(int i=1;i<=len;i++)
for(int j=0;j<=n;j++)
for(int k=0;k<=100;k++)
{
dp[i][j][k]+=dp[i-1][j][k+1]; //遇到花
if(j&&k%2==0) dp[i][j][k]+=dp[i-1][j-1][k/2]; //遇到店
dp[i][j][k]%=mod;
}
dp[len][n][0]=dp[len-1][n][1]; //最后遇到的一个一定是花
cout<
砍竹子
#include
using namespace std;
typedef pairPII;
priority_queueq;
int main()
{
int n;
cin>>n;
long long ans=0;
for(int i=1;i<=n;i++)
{
long long t;
scanf("%lld",&t);
if(t!=1)
q.push({t,i});
}
while(!q.empty())
{
long long t=q.top().first;//记录当前竹子的高度
int r=q.top().second;//记录当前竹子的编号
q.pop();
long long l=sqrt(t/2+1);
if(l!=1)
q.push({l,r});
while(!q.empty()&&q.top().first==t&&q.top().second==r-1)
{
r--;
q.pop();//将队首竹子pop
if(l!=1)
q.push({l,r});//将砍完后的竹子放入优先队列
}
ans++;//当发现竹子高度不一致或者编号不连续时记录一次砍的次数
}
printf("%lld",ans);
return 0;
}