題目鏈接:
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=354
題目意思:
判斷n個人的重量是否超過電梯的總載重量。
解題思路:
水題
代碼:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int res=0;
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
res+=a;
}
if(res>m)
printf("Warning\n");
else
printf("Safe\n");
}
return 0;
}
迭代加深搜索,因爲總分組數很少,深度不會很大。
解題報告:http://blog.csdn.net/cc_again/article/details/25566503
將限制條件轉化去掉後轉化成揹包問題,要注意常數優化,排個序&把第一個單獨拿出來考慮。
解題報告:http://blog.csdn.net/cc_again/article/details/25984915
題目意思:
有n個人,每個人有一個ID、分數和進公司日期,要把這n個人分成6個等級。
分法:分數爲0的人等級爲1,達不到等級爲3或者更高的人等級爲2,分越高者等級越高,分數一樣者先進公司者等級高,如果還一樣誰的ID小者等級高。
告訴每個等級的人數,輸出每個人所在的等級。
解題思路:
模擬
先把人按分數高+進公司日期早+ID號小的優先順序排序,然後從等級高的開始往下分配,直到每個等級的人都分配完了。注意等級1的人得0分,是固定不變的。
代碼:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define Maxn 2200
struct PP
{
int yy,mm,dd,id,s;
int pos,le;
}pp[Maxn];
int ans[Maxn],num[10],n,zh;
bool cmp(PP a,PP b)
{
if(a.s!=b.s)
return a.s>b.s;
if(a.yy>b.yy)
return false;
else if(a.yy<b.yy)
return true;
if(a.mm>b.mm)
return false;
else if(a.mm<b.mm)
return true;
if(a.dd>b.dd)
return false;
else if(a.dd<b.dd)
return true;
return a.id<b.id;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
zh=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d/%d/%d%d",&pp[i].id,&pp[i].yy,&pp[i].mm,&pp[i].dd,&pp[i].s);
//printf(":%d %d %d\n",pp[i].yy,pp[i].mm,pp[i].dd);
if(pp[i].s>0)
zh++;
pp[i].pos=i;
}
num[6]=(int)floor(zh*0.03); //計算每個等級的人數
num[5]=(int)floor(zh*0.07);
num[4]=(int)floor(zh*0.2);
num[3]=(int)floor(zh*0.3);
sort(pp+1,pp+n+1,cmp);
/*for(int i=1;i<=n;i++)
printf(":%d\n",pp[i].pos);*/
int tt=1;
for(int i=6;i>=3;i--)
{
for(int j=tt;j<(tt+num[i]);j++)
ans[pp[j].pos]=i;
tt=tt+num[i];
}
for(int i=tt;i<=n;i++)
{
if(pp[i].s)
ans[pp[i].pos]=2;
else
ans[pp[i].pos]=1;
}
for(int i=1;i<=n;i++)
printf("LV%d\n",ans[i]);
}
return 0;
}
F. zoj 3772 Calculate the Function
線段樹維護區間的矩陣乘積後的矩陣,注意矩陣乘法的順序。
解題報告:http://blog.csdn.net/cc_again/article/details/26093941
H. zoj 3773 Power of Fibonacci
題目意思:
求F1^k+F2^k+...+Fn^k
n<=10^18 k<=100000 Fn爲斐波拉契數列的第n項
解題思路:
數論、逆元、二次剩餘。終於知道帶根號的數模上一個數怎麼處理了。
Tips:要求局部的x^(1/y) mod p 的話只要滿足x是p的y次剩餘,就可以由滿足剩餘的那個數代替運算
參考這位大神思路:http://blog.csdn.net/acdreamers/article/details/23039571
代碼:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000009
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define Maxn 110000
LL cc[Maxn],aa[Maxn],bb[Maxn];
LL n,k;
void init()
{
cc[0]=1;
for(LL i=1;i<=100000;i++) //階乘
cc[i]=cc[i-1]*i%M;
aa[0]=bb[0]=1;
for(LL i=1;i<=100000;i++) // a=(sqrt(5)+1)/2 b=(sqrt(5)-1)/2 用一個整數代替
{
aa[i]=aa[i-1]*691504013%M;
bb[i]=bb[i-1]*308495997%M;
}
}
LL quick(LL a,LL b)
{
LL res=1;
while(b)
{
if(b&1)
res=res*a%M;
b>>=1;
a=a*a%M;
}
return res;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
/*for(LL i=7000000;;i++) 5是1000000009的二次剩餘 x^2=5%1000000009 x的一個解爲383008016
{
if(i*i%M==5)
{
printf("%lld\n",i);
break;
}
}*/
init();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&n,&k);
LL ans=0;
for(int r=0;r<=k;r++) //枚舉C(k,r)
{
LL x=aa[k-r]*bb[r]%M; //a^(k-r)*b(r)
LL y=cc[k]; //k!
LL y1=cc[r],y2=cc[k-r];
y=cc[k]*quick(y1,M-2)%M*quick(y2,M-2)%M; //C(k,r) k!/(r!*(k-r)!)
LL temp=x*(quick(x,n)-1)%M*quick(x-1,M-2)%M; //等比數列求和 t*(t^n-1)/(t-1)
if(x==1) //當公比爲1時不能按照這個來求 都爲1 相加得n
temp=n%M;
temp=temp*y%M; //乘上C(k,r)
if(r&1)
ans=((ans-temp)%M+M)%M;
else
ans=(ans+temp)%M;
}
LL temp=quick(383008016,M-2); //最後還有個(1/sqrt(5))^k次方 先求出逆元
ans=ans*quick(temp,k)%M; //相乘即可得出結果
printf("%lld\n",ans);
}
return 0;
}
/*
383008016
*/
I. zoj 3775 ?(>_0)!
題目意思:
給一種語言,告訴規則,讓你判斷這種語言輸出的結果和源代碼是否一樣。
解題思路:
實際上只用判斷’_'和‘!'的個數就可以解決問題了。
’_'最多隻能有一個,因爲它的意思是把源代碼按原型輸出一遍,如果存在‘!'那麼原文一定是“hello, world!hello, world!..."且出現的次數和‘!'出現的次數應該一樣。
注意考慮空串的情況。
代碼:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define Maxn 440
char save[Maxn];
char ba[]={"Hello, world!"};
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
getchar();
while(t--)
{
gets(save);
int len=strlen(save),ans0=0,ans1=0;
for(int i=0;i<len;i++)
{
if(save[i]=='_')
ans0++;
else if(save[i]=='!')
ans1++;
}
if(ans0>1) //'_'超過1個肯定不行
{
printf("No\n");
continue;
}
if(ans0==1) //恰好爲1個
{
if(ans1) //如果存在'!'也不行
{
printf("No\n");
}
else
printf("Yes\n");
continue;
}
if(ans1==0) //沒有'_' 且沒有'!'
{
if(!len) //如果是空串 這種情況沒考慮的話會wa
printf("Yes\n");
else //否則不行
printf("No\n");
continue;
}
bool flag=true; //判斷'!'的個數是否和“hello, world!"出現的個數一樣
int i=0,j=0;
while(i<ans1&&j<len)
{
if(strncmp(save+j,ba,13)!=0)
{
flag=false;
break;
}
i++;
j+=13;
}
if(i!=ans1||j!=len)
flag=false;
if(!flag)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}