由于有些事情,咕咕了,现在补上。
Luogu P7075
这道题其实就是个模拟题,就是有几个点要注意一下:
1. 没有公元⚪年
2. 1582.10.4的下一天是1582.10.15
3. 1582年之前的闰年只要%4==0
即可,而1582年之后就是%4==0 && %100!=0
(公元前的闰年的计算方法就是Abs(year)-1在判断就好了)
解决方法:
1. 在 1 BC 需要向后推一年的时侯特判一下,直接跳到公元1年
2. 在days超过1582.10.4的时候+10天
3. 写2个闰年判断函数
#include <bits/stdc++.h>
#define int long long
using namespace std;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int dx;
inline int Abs(int x) { return x<0?-x:x; }
inline bool isRyear1(int x) {
if(x<0) x=Abs(x+1);
if(!(x%4)) return 1;
return 0;
}
inline bool isRyear2(int x) {
if((!(x%4)&&(x%100))||(!(x%400)))
return 1;
return 0;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
int Q;
cin>>Q;
while(Q--) {
cin>>dx;
if(dx>2299160)
dx+=10;
int yx=-4713;
while(dx>=146100&&yx+400<1582) {
dx-=146100;
if(yx<=-1&&yx+400>=0) yx+=401;
else yx+=400;
}
for(int i=0,ys=365;i<400;i++) {
if((yx<=1582&&isRyear1(yx))||(yx>1582&&isRyear2(yx))) ys=366;
else ys=365;
if(dx>=ys) dx-=ys;
else break;
if(yx==-1) yx++;
yx++;
}
if(dx>=146097)
yx+=dx/146097*400,dx%=146097;
for(int i=0,ys=365;i<400;i++) {
if((yx<=1582&&isRyear1(yx))||(yx>1582&&isRyear2(yx))) ys=366;
else ys=365;
if(dx>=ys) dx-=ys;
else break;
yx++;
}
if(dx==0) {
if(yx<0) cout<<"1 1 "<<Abs(yx)<<" BC\n";
else cout<<"1 1 "<<yx<<'\n';
continue;
}
if((yx<=1582&&isRyear1(yx))||(yx>1582&&isRyear2(yx))) days[2]++;
for(int i=1;i<=12&&dx>=0;i++) {
if(dx<days[i]) {
if(yx<0) cout<<dx+1<<' '<<i<<' '<<Abs(yx)<<" BC"<<'\n';
else cout<<dx+1<<' '<<i<<' '<<yx<<'\n';
}
dx-=days[i];
}
if((yx<=1582&&isRyear1(yx))||(yx>1582&&isRyear2(yx))) days[2]--;
}
return 0;
}
//146097 the days of 400 years (after 1582)
//146100 the days of 400 years (before 1582)
Luogu P7056
题目大意 :
一共有\(\ 2^k\)种动物,每种动物都有一个编号\(\ a_i\),如果满足\(\ a_i\)的二进制下的第\(\ p_j\)位是\(\ 1\),那么就要购买第\(\ q_i\)种饲料。
请问:如果不再多买饲料,动物园还可以饲养几只动物。
这题就是一个思维题,只要把输入的每一个\(\ a_i\)都\(or\)起来,再统计一下有几位是\(1\),最后输出\(\ 2^x-n\) (\(\ x\)为\(\ k-\) (\(\ 1\)的总个数))
最后输出的时候只要注意一下\(\ 2^{64}\)是超过\(ull\)的范围的(\(CCF\)传统艺能)
#include <bits/stdc++.h>
#define int unsigned long long
using namespace std;
int n,m,c,k;
bool mark[65];
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m>>c>>k;
int tmp=0;
for(int i=1;i<=n;i++) {
int x; cin>>x;
tmp|=x;
}
for(int i=1;i<=m;i++) {
int p,q; cin>>p>>q;
if(!((tmp>>p)&1))
mark[p]=1;
}
for(int i=0;i<65;i++)
if(mark[i]) k--;
if(k==64) {
if(!n)
puts("18446744073709551616");
else
cout<<(1ull<<(k-1))-n+(1ull<<(k-1))<<'\n';
}
else
cout<<(1ull<<k)-n<<'\n';
return 0;
}
CF1000A Codehorses T-shirts
题目大意:
给定\(n\)个字符串和模式串,求出将所有字符串改成和模式串相同所需的最少修改次数(不可改变长度)。
只要暴力将每个长度相等的字符串都与模式串暴力匹配一遍,取\(min(x_1,x_2,...)\)相加即可。
#include<bits/stdc++.h>
#define MAXN 105
using namespace std;
int n,ans;
string s1[MAXN],s2[MAXN];
map<string,int>mark;
inline int f(int y,int x) {
int tot=0;
for(int i=0;i<s1[x].size();i++)
if(s1[x][i]!=s2[y][i])
tot++;
return tot;
}
signed main() {
cin>>n;
for(int i=1;i<=n;i++)
cin>>s1[i],mark[s1[i]]++;
for(int i=1;i<=n;i++)
cin>>s2[i],mark[s2[i]]--;
for(int i=1;i<=n;i++)
if(mark[s2[i]]<0) {
int M=INT_MAX,pos=-1;
for(int j=1,t;j<=n;j++)
if(mark[s1[j]]>0&&s1[j].size()==s2[i].size())
if(M>(t=f(i,j)))
M=t,pos=j;
ans+=M;
mark[s2[i]]++,mark[s1[pos]]--;
}
cout<<ans<<endl;
return 0;
}