山东省第六届ACM省赛
| ID.Title | Hint |
| A.Nias and Tug-of-War | sort排序 |
| B.Lowest Unique Price | set+map |
| C.Game! | 博弈 |
| D.Stars | |
| E.BIGZHUGOD and His Friends I | 赛瓦定理 |
| F.BIGZHUGOD and His Friends II | 赛瓦定理 |
| G.Cube Number | 质因数分解 |
| H.Square Number | 质因数分解 |
| I.Routing Table | |
| J.Single Round Math | 大数 |
| K.Last Hit | |
| L.Circle of Friends | 缩点 |
A.Nias and Tug-of-War
s.sort排序
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std; struct node{
double a;
double b;
}a[]; bool cmp(node a,node b){
//if(a.a!=b.a)
return a.a<b.a;//a升
//return a.b>b.b;//b降
} int main(){ int T;
int N;
int i;
double sum1,sum2; scanf("%d",&T); while(T--){ scanf("%d",&N); for(i=;i<N;++i){
scanf("%lf%lf",&a[i].a,&a[i].b);
} sort(a,a+N,cmp); sum1=;
for(i=;i<N;i+=){
sum1+=a[i].b;
}
sum2=;
for(i=;i<N;i+=){
sum2+=a[i].b;
} if(sum1>sum2){
printf("red\n");
}
else if(sum2>sum1){
printf("blue\n");
}
else{//避免比较相等
printf("fair\n");
}
} return ;
}
B.Lowest Unique Price
s.set+map
#include<iostream>
#include<stdio.h>
#include<set>
#include<map>
using namespace std; int main(){ int T;
int N;
char str[];
int x;
int i;
set<int> myset;
map<int,int> mymap; scanf("%d",&T); while(T--){ myset.clear();
mymap.clear(); scanf("%d",&N); for(i=;i<N;++i){
scanf("%1s",str); if(str[]=='b'){
scanf("%d",&x);
myset.insert(x);
++mymap[x];
if(mymap[x]>){//多于一次价格x
myset.erase(x);
}
}
else if(str[]=='c'){
scanf("%d",&x);
--mymap[x];
if(mymap[x]==){//撤销一次没有价格x
myset.erase(x);
}
else if(mymap[x]==){//撤销一次只剩一次价格x
myset.insert(x);
}
}
else{
if(!myset.empty()){
printf("%d\n",*myset.begin());
}
else{
printf("none\n");
}
} } } return ;
}
C.Game!
s.博弈。当石子个数大于2时,后手赢。
还得看看博弈,做做题。
#include<iostream>
#include<stdio.h>
using namespace std; int main(){ int T;
long long N; scanf("%d",&T); while(T--){ scanf("%lld",&N); if(N>){
printf("blankcqk\n");
}
else{
printf("zbybr\n");
} } return ;
}
D.Stars
E.BIGZHUGOD and His Friends I
F.BIGZHUGOD and His Friends II
G.Cube Number
d.Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a cube number.
s.和下个平方数类似,不错凑立方数的时候,不是从某个数中选2个数了,而是根据这个数的质因数的个数,把每个质因数凑成3个,这样可能直接用这个数乘上相应的数就行了。
ps:long long,还有数组越界的判断搞了好久。。
/*
质因数分解
*/
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std; const int MAXN=;
const long long MAXN2=+;//数字范围 long long num[MAXN2]; int factors[MAXN][];//[0]存质因子,[1]存个数
int factCnt;//不同的质因子总个数 int getFactors(int n){ int i,k;
factCnt=;
for(i=,k=sqrt(n);i<=k;++i){
if(n%i==){
factors[factCnt][]=i;
factors[factCnt][]=;
n=n/i;
while(n%i==){
++factors[factCnt][];
n=n/i;
}
++factCnt;
k=sqrt(n);//循环条件不直接写i<=sqrt(n);是因为这样可以避免重复开跟方
}
}
if(n>){
factors[factCnt][]=n;
factors[factCnt][]=;
++factCnt;
} int temp=;
int j;
for(i=;i<factCnt;++i){
factors[i][]=factors[i][]%;
if(factors[i][]!=){
for(j=;j<factors[i][];++j){
temp=temp*factors[i][];
}
}
}
return temp;
} int main(){
int T;
int N;
int t;
int i,j,k;
long long ans;
long long tmp;
int temp;
bool flag; scanf("%d",&T); while(T--){
scanf("%d",&N);
memset(num,,sizeof(num));
for(i=;i<N;++i){
scanf("%d",&t);
if(t==){
++num[];
continue;
}
temp=getFactors(t);
++num[temp];
} ans=;
for(i=;i<MAXN2;++i){
if(num[i]!=){ temp=getFactors(i); tmp=;
flag=true;
for(j=;j<factCnt;++j){
for(k=;k<-factors[j][];++k){
tmp=tmp*factors[j][];
if(tmp>=MAXN2){
flag=false;
break;
}
}
if(flag==false){
break;
}
} if(tmp>=MAXN2){
continue;
} if(num[tmp]!=){
ans=ans+num[i]*num[tmp];
}
}
} ans=ans/;
if(num[]!=){//1的时候特殊处理
ans=ans+num[]*(num[]-)/;
} printf("%lld\n",ans);
} return ;
}
H.Square Number
d.Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a square number.
s.质因数分解。如果某个质因子的个数为偶数,直接去掉;为奇数时保留一个。这样就缩小了规模。
最后遍历一遍,如果某个数存在,那就从中选出2个就可构成一个平方数,这个数形成的平方数的总个数就是C(n,2)。
/*
质因数分解
*/
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std; const int MAXN=; int factors[MAXN][];//[0]存质因子,[1]存个数
int factCnt;//不同的质因子总个数 #define MAXN2 1000000+10
int num[MAXN2]; void getFactors(int n){
int i,k;
factCnt=;
for(i=,k=sqrt(n);i<=k;++i){
if(n%i==){
factors[factCnt][]=i;
factors[factCnt][]=;
n=n/i;
while(n%i==){
++factors[factCnt][];
n=n/i;
}
++factCnt;
k=sqrt(n);//循环条件不直接写i<=sqrt(n);是因为这样可以避免重复开跟方
}
}
if(n>){
factors[factCnt][]=n;
factors[factCnt][]=;
++factCnt;
} int temp=;
for(i=;i<factCnt;++i){
factors[i][]=factors[i][]%;
if(factors[i][]!=){
temp=temp*factors[i][];
}
} ++num[temp]; } int main(){
/*
int n;
while(~scanf("%d",&n)){ getFactors(n); printf("不同的质因子总个数:%d\n",factCnt); int i,j;
for(i=0;i<factCnt;++i){
for(j=0;j<factors[i][1];++j){
printf("%d ",factors[i][0]);
}
} printf("\n");
}
*/
int T;
int N;
int t;
int i;
int ans;
int j; scanf("%d",&T); while(T--){
scanf("%d",&N);
memset(num,,sizeof(num));
for(i=;i<N;++i){
scanf("%d",&t);
if(t==){
++num[];
continue;
}
getFactors(t);
} ans=;
for(i=;i<MAXN2;++i){ if(num[i]!=){
//cout<<i<<" "<<num[i]<<endl;
ans=ans+(num[i]*(num[i]-))/;
}
} printf("%d\n",ans);
} return ;
}
c2.这个代码可以参考下。
#include <stdio.h>
#include <string.h>
#define MAX 1000010
int pri[];
int dp[];
int vis[MAX];
int amount=;
void init()
{
for(int i=;i<=;i++)
{//素数打表
for(int j=i+i;j<=;j+=i)
{
if(!pri[j])
pri[j]=;
}
}
//平方数打表
for(int i=;i<=;i++)
if(!pri[i])
dp[amount++]=i*i;
} int main()
{
int T,n;
int t;
int i,j;
init();
scanf("%d",&T);
while(T--)
{
memset(vis,,sizeof(vis));
int ans=;
scanf("%d",&n);
for(i=;i<n;i++)
{
scanf("%d",&t);
for(j=;j<amount;j++)
{
if(t%dp[j]==)
{
while(t%dp[j]==)
t/=dp[j];
}
}
ans+=vis[t];
//除去平方因数后的值 ,有多少个该平方因数的值就可以组成多少对
vis[t]++;
}
printf("%d\n",ans);
}
return ;
}
I.Routing Table
J.Single Round Math
s.唯一比较坑的是N要等于M,然而并没从题意看出来。。
c.java大数,注意类名要为Main
import java.math.BigInteger;
import java.util.Scanner; public class Main {//类名要用Main
public static void main(String[] args){ int T;
BigInteger N,M;
BigInteger MOD=new BigInteger("11");
BigInteger ZERO=new BigInteger("0");
Scanner sc=new Scanner(System.in); T=sc.nextInt();
while((T--)>0){ N=sc.nextBigInteger();
M=sc.nextBigInteger(); if(N.compareTo(M)==0&&N.mod(MOD).compareTo(ZERO)==0){//
System.out.println("YES");
}
else{//
System.out.println("NO");
} } }
}
K.Last Hit
L.Circle of Friends
d.
s.强连通分量缩点
ps:这里这个缩点方式可能有重边。
我感觉用set可能解决重边的问题。
另外缩点应该用桥来缩比较好。(好像发现是无向图有桥。。。)
/*
Tarjan算法
复杂度O(N+M)
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std; const int MAXN=+;//点数
const int MAXM=+;//边数
struct Edge{
int to,next;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
int Index,top;
int scc;//强连通分量的个数
bool Instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
//num数组不一定需要,结合实际情况 void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void Tarjan(int u){
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
for(int i=head[u];i!=-;i=edge[i].next){
v=edge[i].to;
if(!DFN[v]){
Tarjan(v);
if(Low[u]>Low[v])Low[u]=Low[v];
}
else if(Instack[v]&&Low[u]>DFN[v])
Low[u]=DFN[v];
}
if(Low[u]==DFN[u]){
scc++;
do{
v=Stack[--top];
Instack[v]=false;
Belong[v]=scc;
num[scc]++;
}
while(v!=u);
}
}
void solve(int N){
memset(DFN,,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,,sizeof(num));
Index=scc=top=;
for(int i=;i<N;i++)
if(!DFN[i])
Tarjan(i);
}
void init(){
tot=;
memset(head,-,sizeof(head));
} int N,M;
struct Node{
int u;
int steps;
};
vector<int> g[MAXN];
int ans;
void bfs(){
queue<Node> myQueue; Node tmp;
tmp.u=Belong[];
tmp.steps=; myQueue.push(tmp); Node u,v;
int i; while(!myQueue.empty()){ u=myQueue.front();
myQueue.pop(); if(u.u==Belong[N-]){
ans=u.steps;
break;
} for(i=;i<g[u.u].size();++i){
v.u=g[u.u][i];
v.steps=u.steps+;
myQueue.push(v);
}
}
} int main(){ int T;
//int N,M;
int i,j;
int u,v;
int a,b;
scanf("%d",&T); while(T--){
init();
scanf("%d%d",&N,&M);
for(i=;i<M;++i){
scanf("%d%d",&u,&v);
addedge(u,v);
}
solve(N); for(i=;i<=scc;++i){
g[i].clear();
}
for(i=;i<N;++i){
for(j=head[i];j!=-;j=edge[j].next){
a=Belong[i];
b=Belong[edge[j].to];
if(a!=b){ g[a].push_back(b);
}
}
} ans=-;
bfs();
printf("%d\n",ans);
} return ;
}
山东省第六届ACM省赛的更多相关文章
- 山东省第六届ACM省赛 H---Square Number 【思考】
题目描述 In mathematics, a square number is an integer that is the square of an integer. In other words, ...
- 山东省第七届ACM省赛------Memory Leak
Memory Leak Time Limit: 2000MS Memory limit: 131072K 题目描述 Memory Leak is a well-known kind of bug in ...
- 山东省第七届ACM省赛------Reversed Words
Reversed Words Time Limit: 2000MS Memory limit: 131072K 题目描述 Some aliens are learning English. They ...
- 山东省第七届ACM省赛------Triple Nim
Triple Nim Time Limit: 2000MS Memory limit: 65536K 题目描述 Alice and Bob are always playing all kinds o ...
- 山东省第七届ACM省赛------The Binding of Isaac
The Binding of Isaac Time Limit: 2000MS Memory limit: 65536K 题目描述 Ok, now I will introduce this game ...
- 山东省第七届ACM省赛------Fibonacci
Fibonacci Time Limit: 2000MS Memory limit: 131072K 题目描述 Fibonacci numbers are well-known as follow: ...
- 山东省第七届ACM省赛------Julyed
Julyed Time Limit: 2000MS Memory limit: 65536K 题目描述 Julyed is preparing for her CET-6. She has N wor ...
- 第六届acm省赛总结(退役贴)
前言: 这是我的退役贴,之前发到了空间里,突然想到也要在博客里发一篇,虽然我很弱,但是要离开了还是有些感触,写出来和大家分享一下,希望不要见笑.回来看看,这里也好久没有更新了,这一年确实有些懈怠,解题 ...
- 山东省第十届ACM省赛参赛后的学期总结
5.11,5.12两天的济南之旅结束了,我也参加了人生中第一次正式的acm比赛,虽然是以友情队的身份,但是我依旧十分兴奋. 其实一直想写博客来增加自己的能力的,但是一直拖到现在,正赶上老师要求写一份总 ...
随机推荐
- SQL2005中设置自动编号字段【转】
如果希望重新定义在表中添加新记录时该列中自动生成并存储于列中的序列号,则可以更改该列的标识属性.在每个表中只能设置一个列的标识属性. 具有标识属性的列包含系统生成的连续值,该值唯一地标识表中的每一行( ...
- C++ 拆分字符串-copy()
c++拆分字符串方法: #include <iostream>#include <string>#include <sstream>#include <alg ...
- ToggleButton与Switch
状态开关按钮togglebutton和开关switch 状态开关按钮togglebutton和开关switch是由button派生出来的,本质也是按钮,支持BUtton的各种属性,从功能上看,Togg ...
- 【dubbo】dubbo-admin在jdk 1.8上部署出错问题
今天在linux上部署dubbo-admin-2.5.4,一直报错: ERROR context.ContextLoader - Context initialization failedorg.sp ...
- bzoj2289: 【POJ Challenge】圆,圆,圆
Description 1tthinking随便地画了一些圆. ftiasch认为这些圆有交集(面积非零)的可能性不大.因为他实在画了太多圆,所以你被请来判断是否存在交集. Input 第1行,一个整 ...
- js实现windows扫雷(jquery)
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- KB975517 "The update does not apply to your system"
https://www.manageengine.com/products//desktop-central/patch-management/Windows-Vista-Ultimate-Editi ...
- 使用eclipse和maven生成java web程序war包
一.eclipse中,在需要打包的项目名上右击,然后把鼠标光标指向弹出框中的“run as”: 二.之后会看到在这个弹出框的右侧会出现一个悬浮窗,如下: 三.在上边的第二个悬浮窗鼠标点击“maven ...
- div+css之清除浮动
当元素有浮动属性时,会对其父元素或后面的元素产生影响,会出现一个布局错乱的现象,可以通过清除浮动的方法来解决浮动的影响. 浮动的清理(clear): 值:none:默认值.允许两边都可以有浮动对象:l ...
- Apache日志不记录图片文件设置方法和来源日志的配置
Apache日志不记录图片文件设置方法 <FilesMatch "\.(ico|gif|jpg|swf)">SetEnv IMAG 1</FilesMatch&g ...