彩笔大三了还去打hdu大一的比赛,看各路大神一小时内各种AK,彩笔多花了一倍的时间才做完。06不是admin及时回答了提问估计要卡到比赛结束。附上题解:
A.搬砖
这个题按照题目逆序来感觉不好做啊。然后想想可以写成递推的形式。对于x来言,如果x是奇数,那么dp[x]=dp[x/2]+dp[x/2+1]+1...否则就是dp[x/2]的2倍...算是简单递推吧..
#include
using namespace std;
int dp[10000007];
int main()
{
dp[1]=0;dp[2]=0;
for(int i=3;i<=10000000;i++)
{
if(i%2)
dp[i]+=dp[i/2+1]+dp[i/2]+1;
else
dp[i]+=2*dp[i/2];
}
int t;
cin>>t;
while(t--)
{
int n;
scanf("%d",&n);
printf("%d\n",dp[n]);
}
return 0;
}
简单模拟题..按照题意来就好了。
#include
using namespace std;
int main()
{
int n,a,b,c;
while(scanf("%d %d %d %d",&n,&a,&b,&c)!=EOF)
{
int sum=0,ans=0;
int v;
for(int i=1;i<=n;i++)
{
scanf("%d",&v);
sum+=v;
if(sum>=a&&sum=b&&sum=c)
{
ans+=4;
sum=0;
}
}
printf("%d\n",ans);
}
return 0;
}
概率系列一直是弱项,看了半天才明白。就是如果直接可以赢那么概率就是1,然后就是可以换任意一个的点数,那么我们枚举三个骰子分别被更换点数后获胜的概率,取最大就好了,因为这个人比较聪明...
#include
using namespace std;
#define ll long long
int T;
int b[10];
int jiance(int x, int y, int z){
if(x == y && y == z &&x == z) return 3;
else if(x == y||y == z || x == z) return 2;
else return 1;
}
pair zhao2(int x, int y, int z){
if(x == y) return make_pair(x, z);
if(y == z) return make_pair(y, x);
if(x == z) return make_pair(x, y);
}
int a[10];
bool jiance(int *b){
for(int i=1; i<=6; i++) a[i] = b[i];
sort(a+1, a+4);
sort(a+4, a+7);
int flag1 = jiance(a[1], a[2], a[3]);
int flag2 = jiance(a[4], a[5], a[6]);
if(flag1 > flag2){
return true;
}
else if(flag1 == flag2){
if(flag1 == 3&&a[1] > a[4])return true;
else if(flag1 == 2){
pair t1 = zhao2(a[1], a[2], a[3]);
pair t2 = zhao2(a[4], a[5], a[6]);
if(t1.first > t2.first) return true;
else if(t1.first == t2.first && t1.second > t2.second) return true;
}
else if(flag1 == 1){
int flag = 0;
if(a[6] > a[3]) flag = 1;
else if(a[6] == a[3]){
if(a[5] > a[2]) flag = 1;
else if(a[5] == a[2]){
if(a[4] >= a[1]) flag = 1;
else flag = -1;
}
else flag = -1;
}
else flag = -1;
if(flag == -1) return true;
}
}
return false;
}
int main(){
cin>>T;
while(T--){
for(int i=1; i<=6; i++) scanf("%d", &b[i]);
bool res = jiance(b);
int ans = 0;
double rrr = 0;
if(res) printf("1.000\n");
else{
for(int i=1; i<=3; i++){
ans = 0;
for(int j=1; j<=6; j++){
int tmp = b[i];
b[i] = j;
if(jiance(b)){
ans ++;
}
b[i] = tmp;
}
rrr = max(rrr, ans*1.0/6);
}
printf("%.3f\n", rrr);
}
}
return 0;
}
这个题范围10^8,所以我们打表出10^5以内的就可以了,10^4不太稳...因为万一大于10^8的离得最近怎么办...
然而我第一次用了二分WA了..不知道为啥,然后我换暴力过了- -真是太弱了。
#include
using namespace std;
#define ll long long
int ss[100007],ssb[100007];
int sscnt;
void db()
{
sscnt=0;
memset(ss,0,sizeof(ss));
ss[1]=1;
for(int i=2;i<=100000;i++)
{
if(ss[i]==0)
{
ssb[sscnt++]=i;
for(int j=i+i;j<=100000;j+=i)
ss[j]=1;
}
}
}
int main()
{
db();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
ll ans=100000000000;
for(int i=0;i
E.ACM组队安排
高中排列组合知识,弱打表过的...附上递推关系,k[i]为i个人组队情况综述。
k[i]=k[i-1]+k[i-2]*(i-1)+k[i-3]*(i-1)*(i-2)/2。
k[i-1]:新加的第i个人自己一队,其他人按照以前的方式组队
k[i-2]*(i-1):第i人与前i-1人中跳出一人组队,剩下的参考i-2人的组队
k[i-3]*(i-1)*(i-2)/2:第i人与前i-1人挑出2人组队,剩下的按照i-3人组队情况。
这个题就不上代码了。
F.逆袭指数
这个题的正确题意就是找出n最多有多少个连续的因子,而且这些因子相乘后的结果也是n的因子。
题意不明朗一直WA。然而get到正确题意就AC了。
通过种种方法我们可以得知n的因子数不会超过5000...直接暴力就好了。
#include
using namespace std;
#define ll long long
int n;
int yz[200000],ss;
void fj(int n)
{
ss=0;
yz[ss++]=n;
int m=sqrt(n);
for(int i=2; i<=m; i++)
{
if(n%i==0)
{
yz[ss++]=i;
if(i*i!=n)
yz[ss++]=n/i;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)
{
printf("1\n0\n");
continue;
}
fj(n);
sort(yz,yz+ss);
int len=1,ans=0;
for(int i=0; ilen)
{
len=tmp;
ans=i;
}
}
printf("%d\n%d",len,yz[ans]);
for(int i=ans+1;i
G.油菜花王国
简单并查集...完全不用考虑题目说的重边...刚开始写错判断条件过样例了还傻逼的WA了一发。
#include
using namespace std;
#define ll long long
int f[1234],r[1234];
ll fb[70];
int finde(int x)
{
if(f[x]!=x)
return f[x]=finde(f[x]);
return x;
}
int main()
{
fb[1]=1,fb[2]=2;
for(int i=3;i<=50;i++)
{
fb[i]=fb[i-1]+fb[i-2];
}
int n,m;
ll c;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=n;i++)
{
int j;
scanf("%lld",&c);
for(j=1;j<=50;j++)
if(c<=fb[j]) break;
if(c==fb[j])
r[i]=1;
else
r[i]=0;
}
int u,v;
for(int i=0;i
简单贪心,先把m个选择的搞定,剩下的贪心选择就就好了,注意不要重复选择某个项目....
#include
using namespace std;
#define ll long long
struct node
{
int c,x;
}s[20000];
int cmp(node a,node b)
{
return a.x>t;
while(t--)
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
int ans=0,p;
for(int i=0;i=s[p-1].x)
{
k-=s[p-1].x;
s[p-1].c=1;
ans++;
}
}
if(ans