Problem B: 985的数学难题
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 85 Solved: 13
Submit Status Web Board
Description
Input
Output
一个整数代表最后的返回值ans。
Sample Input
Sample Output
HINT
先求各数之和--然后求位运算的值:
位运算的求法可以分位求--
从数大到小--(这样位数不会减少)
每位分为0和1--计算与后面数的位运算
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL n,s,shu[100100],ge[32];
LL ssss[32];
void ss(int xx)
{
int lp=0;
while (xx)
{
if (xx%2)
ge[lp]++;
lp++;
xx/=2;
}
}
bool cmp(int xx,int yy)
{
return xx>yy;
}
void sl(int xx,int pp)
{
int lp=0;
while (xx)
{
if (xx%2)
{
ge[lp]--;
s+=pp*ssss[lp]*2;//||
}
else
{
s+=ge[lp]*ssss[lp]*2;//||
}
xx/=2;
lp++;
}
}
int main()
{
// |=&+^;====2*a|b
ssss[0]=1;
for (int i=1;i<30;i++)
ssss[i]=ssss[i-1]*2;
int t;scanf("%d",&t);
while (t--)
{
scanf("%d",&n);s=0;
for (int i=0;i<n;i++)
{
scanf("%d",&shu[i]);
s+=(n-1)*shu[i];
}
//转化为2个2个的| 运算---
sort(shu,shu+n,cmp);
memset(ge,0,sizeof(ge));
for (int i=0;i<n;i++)
ss(shu[i]);
int op=1;
for (int i=0;i<n-1;i++ )
{
// printf("%d 66\n",shu[i]);
sl(shu[i],n-1-i);
}
printf("%lld\n",s);
}
return 0;
}
/**************************************************************
Problem: 1893
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:942 ms
Memory:1660 kb
****************************************************************/
Problem C: 985的方格难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 330 Solved: 62
Submit Status Web Board
Description
Input
Output
Sample Input
Sample Output
HINT
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL ma[50][50];
int main()
{
int t;scanf("%d",&t);
while (t--)
{
int n,x,y;
scanf("%d%d%d",&n,&x,&y);
memset(ma,0,sizeof(ma));
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (i==x&&j==y)
ma[i][j]=0;
else if (i==1&&j==1)
ma[i][j]=1;
else
ma[i][j]=ma[i-1][j]+ma[i][j-1];
}
}
if (ma[n][n])
{
ma[n][n]=ma[n][n]%1000000007;
printf("%lld\n",ma[n][n]);
}
else
printf("-1\n");
}
return 0;
}
/**************************************************************
Problem: 1894
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:0 ms
Memory:892 kb
****************************************************************/
Problem D: 985的0-1串难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 111 Solved: 19
Submit Status Web Board
Description
985有一个长度为n的0-1串,已知他最多可以修改k次(每次修改一个字符即0->1 或者 1->0),他想知道连续的全1子串最长是多少。
Input
Output
一个整数代表可以得到的最大长度。
Sample Input
Sample Output
HINT
记录一下0的位置--
如果o的个数小于等于k直接输出n
否则求第i个0到第i+k+1个0之间的数--(他们之间有k个0---)
记得在最开始和结束的位置加上两个0---便于计算最前和最后k个0的情况--
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long
int shu[100100];
int he[100100];
int main()
{
int t;scanf("%d",&t);
while (t--)
{
char ch[100100];
int n,k,kp;
scanf("%d%d",&n,&k);
scanf("%s",ch);
kp=0;
shu[kp++]=0;
for (int i=0;i<n;i++)
if (ch[i]=='0')
shu[kp++]=i+1;
if (kp-1<=k)
printf("%d\n",n);
else
{
int mi=-1;
shu[kp++]=n+1;
for (int i=k+1;i<kp;i++)
{
// printf("%d %d %d %d\n",i,i-k-1,shu[i],shu[i-k-1]);
mi=max(shu[i]-shu[i-k-1]-1,mi);
}
printf("%d\n",mi);
}
}
return 0;
}
/**************************************************************
Problem: 1895
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:13 ms
Memory:1676 kb
****************************************************************/
Problem E: 985的买饮料难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 226 Solved: 119
Submit Status Web Board
Description
Input
Output
输出一个整数代表最后的结果。
Sample Input
Sample Output
HINT
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
int main()
{
int t;scanf("%d",&t);
while (t--)
{
int n;scanf("%d",&n);
int mi=9999,s=0;
int a,b;
for (int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
mi=min(b,mi);
s+=a*mi;
}
printf("%d\n",s);
}
return 0;
}
/**************************************************************
Problem: 1896
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:7 ms
Memory:872 kb
****************************************************************/
Problem F: 985的红绿灯难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 205 Solved: 126
Submit Status Web Board
Description
Input
Output
Sample Input
Sample Output
HINT
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
int main()
{
int t;scanf("%d",&t);
while (t--)
{
LL x,g,y,r,s;
scanf("%lld%lld%lld%lld",&x,&g,&y,&r);
s=g+y+r;
x%=s;
if (x<g)
printf("G\n");
else if (x<g+y)
printf("Y\n");
else
printf("R\n");
}
return 0;
}
/**************************************************************
Problem: 1897
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:0 ms
Memory:872 kb
****************************************************************/
Problem G: 985的数字难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 256 Solved: 85
Submit Status Web Board
Description
Input
Output
输出一个整数代表最多可以得到多少个相同的数。
Sample Input
Sample Output
HINT
题解:
如果n个数之和是n的倍数--那么一定可以变成n个相同的数--
如果不能---(贪心)可以让一个数取极值--那么剩下的n-1个数就能变成相同的--
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
int shu[42000],n;
int main()
{
int t,s;scanf("%d",&t);
while (t--)
{
scanf("%d",&n);s=0;
for (int i=0;i<n;i++)
{
scanf("%d",&shu[i]);
s+=shu[i];
}
if (s%n==0)
printf("%d\n",n);
else
printf("%d\n",n-1);
}
return 0;
}
/**************************************************************
Problem: 1898
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:19 ms
Memory:1036 kb
****************************************************************/
Problem H: 985的最大和难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 216 Solved: 11
Submit Status Web Board
Description
985有2 * n - 1个整数,他每次可以将其中n个数变号,操作次数不限,问他可以得到的最大和。
Input
Output
输出一个整数代表可以得到的最大和。
Sample Input
Sample Output
HINT
扩展欧几里德:
(X*P-1)*(2N-1)+(Y*P-1)*N=P-1
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define LL long long
int extend(int a,int b,int &x,int &y)
{
if (b==0)
{
x=1;y=0;
return a;
}
else{
int t=extend(b,a%b,y,x);
y-=(a/b*x);
return t;
}
}
int shu[1020];
int main()
{
int t;scanf("%d",&t);
while (t--)
{
int n;scanf("%d",&n);
int s=0,a,p=2*n-1,zheng,fu=0;
for (int i=0;i<p;i++)
{
scanf("%d",&shu[i]);
if (shu[i]<0)
fu++;
}
int x,y;
extend(p,n,x,y);
x=(x%n+n)%n;
if (fu%2&&x%2)
{
int mi=100000;
for (int i=0;i<p;i++)
{
shu[i]=abs(shu[i]);
s+=shu[i];
}
sort(shu,shu+p);
s-=shu[0]*2;
}
else
{
for (int i=0;i<p;i++)
s+=abs(shu[i]);
}
printf("%d\n",s);
}
return 0;
}
/**************************************************************
Problem: 1899
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:1 ms
Memory:880 kb
****************************************************************/
Problem I: 985的“树”难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 24 Solved: 4
Submit Status Web Board
Description
Input
Output
Sample Input
Sample Output
HINT
回溯法求子节点的数目----LCA中的原理--
wrong的好伤心呀---
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define LL long long
#define MA 40000
struct node{
int to,next;
}bian[MA];
int head[MA];
bool fafe[MA];
void DFS(int xx)
{
int lp;
for (int j=head[xx];j!=-1;j=bian[j].next)
{
lp=bian[j].to;
if (fafe[lp])
{
fafe[lp]=false;
DFS(lp);
}
}
}
int vis[MA*100];
int D[MA],kp;
int ans[MA],wei[MA],ii,fer[MA];
void xun(int xx,int de)
{
D[xx]=de;
vis[kp++]=xx;
for (int j=head[xx];j!=-1;j=bian[j].next)
{
int lp=bian[j].to;
if (fafe[lp])
{
fafe[lp]=false;
fer[lp]=xx;
xun(lp,de+1);
vis[kp++]=xx;
}
}
return ;
}
int main()
{
int t;scanf("%d",&t);
while (t--)
{
int n,boot;
scanf("%d%d",&n,&boot);
for (int i=1;i<=n;i++)
head[i]=-1;
int a,b;
for (int i=0;i<n-1;i++)
{
scanf("%d%d",&a,&b);
bian[2*i].to=a;
bian[i*2].next=head[b];
head[b]=2*i;
bian[2*i+1].to=b;
bian[i*2+1].next=head[a];
head[a]=2*i+1;
}
memset(fafe,true,sizeof(fafe));
fafe[boot]=false;
DFS(boot);
bool falg=true;
for (int i=1;i<=n;i++)
{
if (fafe[i])
{
falg=false;
break;
}
}
if (!falg)
{
printf("NO\n");
continue;
}
memset(D,0,sizeof(D));
kp=1;
memset(fafe,true,sizeof(fafe));
fafe[boot]=false;
xun(boot,1);//错误了--
memset(ans,0,sizeof(ans));
memset(wei,0,sizeof(wei));
for (int i=1;i<kp;i++)
{
ii=vis[i];
if (!wei[ii])
wei[ii]=i;
else
{
ans[ii]+=i-wei[ii];
wei[ii]=i;
}
}
for (int i=1;i<=n;i++)
ans[i]/=2;
printf("YES\n");
for (int i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
for (int i=1;i<=n;i++)
D[i]--;
D[boot]=1;
fer[boot]=boot;
for (int i=1;i<n;i++)
printf("%d ",fer[i]);
printf("%d\n",fer[n]);
}
return 0;
}
Problem J: 985的SS串难题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 37 Solved: 4
Submit Status Web Board
Description
Input
Output
按字典序输出所有不相同的SS串。
Sample Input
Sample Output
HINT
字典树水过(比赛时内存释放应该是出了一些情况---所以我开了12个boot(字典树的根))
然后就是存入单词--输出单词---
用字典树输出字典序好完美-.-
代码:
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
bool fafe[26];
int dui[10]={1,4,9,16,25,2,8,18};
int sl(int xx)
{
for (int i=0;i<8;i++)
if (xx==dui[i])
return true;
return false;
}
struct node{
struct node * chi[26];
char cha[1050];
int fafa;
}boot[12];
//struct node *boot[12] = new node();
void jia(char xx[],int lp)
{
node * kk=&boot[lp];
int ll=strlen(xx),k;
for (int i=0;i<ll;i++)
{
k=xx[i]-'a';
if (!kk->chi[k])
kk->chi[k]=new node();
kk=kk->chi[k];
}
strcpy(kk->cha,xx);
kk->fafa=1;
}
void prin(node * xx)
{
if (xx->fafa)
printf("%s\n",xx->cha);
for (int i=0;i<26;i++)
{
if (xx->chi[i])
prin(xx->chi[i]);
}
}
void booop(node * xx)
{
for (int i=0;i<26;i++)
if (xx->chi[i])
booop(xx->chi[i]);
delete xx;
}
int main()
{
int t,s,kp;scanf("%d",&t);
char ch[1050],pp[1050];
int ca=0;
while (t--)
{
scanf("%s",ch);
int n=strlen(ch);//printf("%d 66\n",n);
for (int i=0;i<n;i++)
{
memset(fafe,false,sizeof(fafe));
s=0;
for (int j=i;j<n;j++)
{
int p=ch[j]-'a';
if (!fafe[p])
{
fafe[p]=true;
s++;
}
if (sl(s))
{
kp=0;
for (int k=i;k<=j;k++)
pp[kp++]=ch[k];
pp[kp]=0;
jia(pp,ca);
}
}
}
for (int i=0;i<26;i++)
{
if (boot[ca].chi[i])
prin(boot[ca].chi[i]);
}
for (int i=0;i<26;i++)
{
if (boot[ca].chi[i])
booop(boot[ca].chi[i]);
}
ca++;
}
return 0;
}
/**************************************************************
Problem: 1901
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:837 ms
Memory:88400 kb
****************************************************************/
Problem K: 985的因子对难题
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 114 Solved: 22
Submit Status Web Board
Description
Input
Output
一个整数代表最后的答案。
Sample Input
Sample Output
HINT
优化:相同数合并--再用类似素数打表的O(nlogn)的计算思路--挤了过去
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define LL long long
int n,shu[1001000],pp[1001000];
int main()
{
int t;scanf("%d",&t);
while (t--)
{
scanf("%d",&n);int a;
memset(shu,0,sizeof(shu));
memset(pp,0,sizeof(pp));
for (int i=0;i<n;i++)
{
scanf("%d",&a);
shu[a]++;
}
for (int i=1;i<=1000000;i++)
{
if (shu[i])
{
for (int j=2*i;j<=1000000;j+=i)
pp[j]+=shu[i];
}
}
LL s=0;
for (int i=1;i<=1000000;i++)
{
if (shu[i])
{
// printf("%d %d %d 66\n",i,shu[i],pp[i]);
if (shu[i]>1)
s+=(shu[i]*(shu[i]-1))/2;
s+=pp[i]*shu[i];
// printf("%lld\n",s);
}
}
printf("%lld\n",s);
}
return 0;
}
/**************************************************************
Problem: 1902
User: Leibniz_Zhang
Language: C++
Result: Accepted
Time:1252 ms
Memory:8692 kb
****************************************************************/