J:https://ac.nowcoder.com/acm/contest/886/J
1.统一类型全int或ll;2.多用min max函数,如果不需要记录位置;3.考虑边界问题,0或最后
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1010;
const ll INF=1e18+5;
ll n,m,x,sum[maxn][maxn];
ll d[maxn],f[maxn][maxn];
int main()
{
int T,ca=0;
scanf("%d",&T);
while(T--){
scanf("%lld%lld",&n,&m);
memset(sum,0,sizeof(sum));
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
scanf("%lld",&x);
sum[i][j]=sum[i][j-1]-x;
}
}
for(ll i=1;i<=n;i++){
for(ll j=m;j>=0;j--){
if(j==m) f[i][j]=sum[i][j];
else f[i][j]=max(f[i][j+1],sum[i][j]);
}
}
d[0]=0;
for(ll i=1;i<=m;i++){
scanf("%lld",&x);
d[i]=d[i-1]+x;
}
ll ans=0,now,mx;
bool flag;
for(ll i=0;i<=m;i++){
mx=INF;
now=d[i];
for(ll j=1;j<=n;j++){
ll rr=f[j][i];
now+=rr;
mx=min(mx,rr-sum[j][i]);
}
ans=max(ans,now-mx);
}
printf("Case #%d: %lld\n",++ca,ans);
}
return 0;
}
B:https://ac.nowcoder.com/acm/contest/886/B
128位 转子网掩码,每16位弄成4位16进制表示,去了前导0,判断变大于等于2个0的时候,暴力模拟即可!
不能懒,自己分析清题意好好写。
1.字符串使用前一定要初始化为空;2. 0:0在最前面和最后面特殊考虑。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> p;
vector<p> vc;
string s,ss[10];
vector<char> v[10];
char m[20]={"0123456789abcdef"};
int main()
{
int t,cc=0;
cin>>t;
while(t--){
cin>>s;
for(int i=0;i<8;i++) v[i].clear();
vc.clear();
int i=0,x=0;
while(i<128){
x=x*2+s[i]-'0';
if((i+1)%4==0){
v[i/16].push_back(m[x]);x=0;
}
i++;
}
for(int i=0;i<8;i++){
int j=0;ss[i]="";
while(j<4&&v[i][j]=='0') j++;
if(j==4) ss[i]="0";
else{
for(int k=j;k<4;k++) ss[i]+=v[i][k];
}
}
int l=-1,r=-1;
for(int i=0;i<8;i++){
if(l==-1&&ss[i]=="0"){
l=i;
}
else if(l!=-1&&ss[i]=="0"){
r=i;
}
else if(ss[i]!="0"){
if(l!=-1&&r!=-1) vc.push_back(p(l,r));
l=-1;r=-1;
}
//cout<<l<<" "<<r<<endl;
}
if(l!=-1&&r!=-1) vc.push_back(p(l,r));
string ans="",temp;
for(int i=0;i<8;i++){
ans+=ss[i];
if(i!=7) ans+=':';
}
int dui=vc.size();
//cout<<dui<<endl;
for(int i=0;i<dui;i++){
temp="";
int ll=vc[i].first,rr=vc[i].second;
for(int j=0;j<ll;j++){
temp+=ss[j];
if(j!=ll-1) temp+=":";
}
temp+="::";
for(int j=rr+1;j<8;j++){
temp+=ss[j];
if(j!=7) temp+=":";
}
//cout<<temp<<endl;
if(temp.size()<ans.size()||(temp.size()==ans.size()&&temp<ans))
ans=temp;
}
cout<<"Case #"<<++cc<<": "<<ans<<endl;
}
return 0;
}
D:https://ac.nowcoder.com/acm/contest/886/D
给出n个物品,k个背包,求装下所有物品所需要的最小背包体积。
1.答案不具有单调性,即00100001111111,所以不能二分;2.每次判断的时候枚举每个背包,从大到小,依次尝试的放。最后判断时候所有的都放完了;3.最小体积的下界sum/k,上界sum/k+maxv。设某个最小体积 ans 装不下,那么每个箱子的剩余空间都 < maxV ,此时 k * (ans - maxV + 1) <= sum(已经放下的) 则ans <= sum/k + maxV - 1。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
int n,k,a[maxn];
bool vis[maxn];
bool judge(int x)
{
memset(vis,false,sizeof(vis));
for(int i=0;i<k;i++){
int v=0;
for(int j=0;j<n;j++){
if(!vis[j]&&v+a[j]<=x){
v+=a[j];
vis[j]=true;
}
}
}
for(int i=0;i<n;i++)
if(!vis[i]) return false;
return true;
}
int main()
{
int t,cc=0;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
int sum=0,mx=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
sum+=a[i];
mx=max(mx,a[i]);
}
sort(a,a+n,greater<int>() );
int l=sum/k,r=l+mx;
for(int i=l;i<=r;i++){
if(judge(i)){
printf("Case #%d: %d\n",++cc,i);
break;
}
}
}
return 0;
}
G:https://ac.nowcoder.com/acm/contest/886/G
蔡勒公式:判断得到星期几
1.0-9全排列,对应ABCDEFGHI表示数字,挨个判断每个日期是否满足。
2.
w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六
c:世纪(注:一般情况下,在公式中取值为已经过的世纪数,也就是年份除以一百的结果,而非正在进行的世纪,也就是现在常用的年份除以一百加一;不过如果年份是公元前的年份且非整百数的话,c应该等于所在世纪的编号,如公元前253年,是公元前3世纪,c就等于-3)
y:年(一般情况下是后两位数,如果是公元前的年份且非整百数,y应该等于cMOD100+100)
m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算)
d:日
[ ]代表取整,即只要整数部分。取余完如果是负数,记得加7。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int p[15];
int month[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
string s[maxn];
bool check(int x)
{
int y=p[(s[x][0]-'A')]*1000+p[(s[x][1]-'A')]*100+p[(s[x][2]-'A')]*10+p[(s[x][3]-'A')];
int m=p[(s[x][5]-'A')]*10+p[(s[x][6]-'A')];
int d=p[(s[x][8]-'A')]*10+p[(s[x][9]-'A')];
if(y%4==0&&(y%100!=0||y%400==0)) month[2]=29;
if(y<1600||y>9999||m<1||m>12||d<1||d>month[m])
return false;
if(m==1||m==2) {
y--;
m+=12;
}
int c=y/100;y=y%100;
int w=(c/4-2*c+y+y/4+(13*(m+1))/5+d-1)%7;
if(w<0) w=(w+7)%7;
//int w=(d+2*m+3*(m+1)/5+y+(y/4)-(y/100)+(y/400)+1)%7;
if(w==5) return true;
else return false;
}
int main()
{
int T,n;
scanf("%d",&T);
for(int ii=1;ii<=T;ii++) {
for(int i=0;i<10;i++)
p[i]=i;
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
sort(s+1,s+1+n);
n=unique(s+1,s+1+n)-s-1;
int flag;
do{
flag=1;
for(int i=1;flag&&i<=n;i++)
if(!check(i)){
flag=0;break;
}
if(flag) break;
}while(next_permutation(p,p+10));
printf("Case #%d: ",ii);
if(flag==0) puts("Impossible");
else {
for(int i=0;i<10;i++) cout<<p[i];
cout<<endl;
}
}
return 0;
}