17青岛网络赛
接连爆炸...
A Cubic number and A Cubic Number
题意:给素数p,问是否存在两个数的立方差等于x.
a3-b3立方差公式展开得(a-b)*(a2+ab+b2) == p
p是素数,所以a-b等于1,于是可以得到3a2+3a+1 == p 即 a(a+1) == (p-1)/3
---场上我没看,队友写的...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 5 int main(){ 6 int t; 7 scanf("%d",&t); 8 ll x; 9 while(t--){ 10 scanf("%lld",&x); 11 x-=1; 12 if(x%3){ 13 puts("NO"); 14 }else{ 15 x=x/3; 16 ll a=sqrt(x); 17 if(a*(a+1)==x) puts("YES"); 18 else puts("NO"); 19 } 20 } 21 return 0; 22 }
Chinese Zodiac
题意:给生肖,算年龄差~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 map<string,int> mp; 5 6 int main(){ 7 int t; 8 scanf("%d",&t); 9 mp["rat"]=1; mp["ox"]=2; mp["tiger"]=3; mp["rabbit"]=4; 10 mp["dragon"]=5; mp["snake"]=6; mp["horse"]=7; mp["sheep"]=8; 11 mp["monkey"]=9; mp["rooster"]=10; mp["dog"]=11; mp["pig"]=12; 12 while(t--){ 13 string a,b; 14 cin>>a>>b; 15 int u=mp[a], v=mp[b]; 16 int ans=(v-u+11)%12+1; 17 cout<<ans<<endl; 18 } 19 }
The Dominator of Strings
题意:给n个字符串,问其中是否存在一个串包含其他所有串.
好像方法很多...
场上一开始想用ac自动机搞,然后不知道为什么把自己否了=_=,,
队友用后缀自动机搞一直TLE,我没学过也帮不上忙...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: yijiull 4 > Mail: 1147161372@qq.com 5 > Create 6 Time: 2017年09月18日 星期一 16时00分57秒 7 ************************************************************************/ 8 9 #include<iostream> 10 #include<cstring> 11 #include<cstdio> 12 #include <bits/stdc++.h> 13 using namespace std; 14 const int maxnode = 100010; 15 const int sigma = 26; 16 17 struct AC{ 18 int ch[maxnode][sigma], last[maxnode], f[maxnode]; 19 int val[maxnode]; 20 int sz; 21 int cnt; 22 23 void init(){ 24 sz = 1; 25 cnt = 0; 26 val[0] = 0; 27 memset(ch[0],0,sizeof(ch[0])); 28 } 29 30 int idx(char s) { 31 return s - 'a'; 32 } 33 34 void insert_(char *s){ 35 int u = 0, n = strlen(s); 36 for(int i = 0; i < n; i++){ 37 int c = idx(s[i]); 38 if(!ch[u][c]){ 39 memset(ch[sz],0,sizeof(ch[sz])); 40 val[sz] = 0; 41 ch[u][c] = sz++; 42 } 43 u = ch[u][c]; 44 } 45 val[u]++; 46 } 47 48 void getfail(){ 49 queue<int> q; 50 f[0] = 0; 51 for(int c = 0; c < sigma; c++){ 52 int u = ch[0][c]; 53 if(u){ 54 f[u] = 0; 55 q.push(u); 56 last[u] = 0; 57 } 58 } 59 while(!q.empty()){ 60 int r = q.front(); 61 q.pop(); 62 for(int c = 0; c < sigma; c++){ 63 int u = ch[r][c]; 64 if(!u){ 65 ch[r][c] = ch[f[r]][c]; 66 continue; 67 } 68 q.push(u); 69 int v = f[r]; 70 while(v && !ch[v][c]) v = f[v]; 71 f[u] = ch[v][c]; 72 last[u] = val[f[u]] ? f[u] : last[f[u]]; 73 } 74 } 75 } 76 77 void print(int u){ 78 if(u){ 79 cnt += val[u]; 80 val[u] = 0; 81 print(last[u]); 82 } 83 } 84 85 void query(char *s){ 86 int u = 0, n = strlen(s); 87 for(int i = 0; i < n; i++){ 88 int c=idx(s[i]); 89 while(u && !ch[u][c]) u = f[u]; 90 u = ch[u][c]; 91 int temp = 0; 92 if(val[u]) temp = u; 93 else if(last[u]) temp = last[u]; 94 while(temp){ 95 cnt += val[temp]; 96 val[temp] = 0; 97 temp = last[temp]; 98 } 99 } 100 } 101 102 }; 103 AC ac; 104 char s[maxnode]; 105 char ans[maxnode]; 106 107 int main(){ 108 int t; 109 scanf("%d", &t); 110 while(t--){ 111 ac.init(); 112 int n; 113 scanf("%d", &n); 114 int maxl = 0; 115 for(int i = 0; i < n; i++){ 116 scanf("%s",s); 117 int len = strlen(s); 118 if(maxl < len){ 119 maxl = len; 120 strcpy(ans,s); 121 } 122 ac.insert_(s); 123 } 124 ac.getfail(); 125 ac.query(ans); 126 if(ac.cnt == n){ 127 puts(ans); 128 }else{ 129 puts("No"); 130 } 131 } 132 return 0; 133 }
看到别人直接KMP更快...
strcpy(char *p, char *s) ; //把s复制给p, 包括最后的'\0'
strncpy(char *p, char *s, int n) ; // 把s的前n个字符复制给p, 不加'\0'
< strncpy并没有拷贝串后的\0字符,而strcpy却拷贝了。
< 这充分说明,strncpy是为拷贝字符而生的,而strcpy是拷贝字符串而生的。但两者都不能越界拷贝。只要正确使用strncpy, 那就比strcpy安全。
然而我写的KMP还是和ac自动机一样的慢...复制字符串太耗费时间=_=
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: yijiull 4 > Mail: 1147161372@qq.com 5 > Created Time: 2017年09月18日 星期一 17时22分46秒 6 ************************************************************************/ 7 8 #include<iostream> 9 #include<cstring> 10 #include<cstdio> 11 #include <bits/stdc++.h> 12 using namespace std; 13 const int maxn=100010; 14 char s[maxn], p[maxn], str[maxn]; 15 int f[maxn]; 16 17 int a[maxn],b[maxn]; 18 int lenp, lens; 19 void getfail(char *p){ 20 f[0] = f[1] = 0; 21 for(int i = 1; i < lenp; i++){ 22 int j = f[i]; 23 while(j && p[j]!=p[i]) j = f[j]; 24 f[i+1] = p[i]==p[j] ? j+1 : 0; 25 } 26 return ; 27 } 28 int kmp(char *s, char *p){ 29 lenp = strlen(p); 30 lens = strlen(s); 31 getfail(p); 32 int j = 0; 33 for(int i = 0; i < lens; i++){ 34 while(j &&s[i]!=p[j]) j = f[j]; 35 if(s[i] == p[j]) j++; 36 if(j == lenp) return 1; 37 } 38 return 0; 39 } 40 41 int main(){ 42 int t; 43 scanf("%d",&t); 44 while(t--){ 45 int n; 46 int len = 0; 47 int maxlen = 0; 48 scanf("%d", &n); 49 for(int i = 0; i < n; i++) { 50 scanf("%s", str+len); 51 a[i] = len; 52 b[i] = strlen(str); 53 len += b[i] - a[i]; 54 if(b[i] - a[i] > maxlen) { 55 maxlen = b[i] - a[i]; 56 strncpy(s,&str[a[i]],b[i]-a[i]); 57 s[b[i]-a[i]]=0; 58 } 59 } 60 int flag = 1; 61 for(int i = 0; i < n; i++) { 62 strncpy(p,&str[a[i]],b[i]-a[i]); 63 p[b[i]-a[i]]=0; 64 if(!kmp(s,p)) { 65 flag = 0; 66 break; 67 } 68 } 69 if(flag) puts(s); 70 else puts("No"); 71 } 72 return 0; 73 }
下面这个是参考的大佬的~ 其实字符串不用复制 ,整整快了2s......
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: yijiull 4 > Mail: 1147161372@qq.com 5 > Created Time: 2017年09月18日 星期一 17时22分46秒 6 ************************************************************************/ 7 8 #include<iostream> 9 #include<cstring> 10 #include<cstdio> 11 #include <bits/stdc++.h> 12 using namespace std; 13 const int maxn=100010; 14 char str[maxn*100]; 15 int f[maxn]; 16 char *p[maxn]; 17 char *s; 18 int lenp, lens; 19 20 void getfail(char *p){ 21 f[0] = f[1] = 0; 22 for(int i = 1; i < lenp; i++){ 23 int j = f[i]; 24 while(j && p[j]!=p[i]) j = f[j]; 25 f[i+1] = p[i]==p[j] ? j+1 : 0; 26 } 27 return ; 28 } 29 int kmp(char *s, char *p){ 30 lenp = strlen(p); 31 lens = strlen(s); 32 getfail(p); 33 int j = 0; 34 for(int i = 0; i < lens; i++){ 35 while(j &&s[i]!=p[j]) j = f[j]; 36 if(s[i] == p[j]) j++; 37 if(j == lenp) return 1; 38 } 39 return 0; 40 } 41 42 int main(){ 43 int t; 44 scanf("%d",&t); 45 while(t--){ 46 int n; 47 int len = 0; 48 int maxlen = 0; 49 scanf("%d", &n); 50 char *o=str; 51 for(int i = 0; i < n; i++) { 52 scanf("%s", o); 53 len = strlen(o); 54 if(len > maxlen) { 55 maxlen = len; 56 s = o; 57 } 58 p[i] = o; 59 o += strlen(o) + 2; //!!! 60 } 61 62 int flag = 1; 63 for(int i = 0; i < n; i++) { 64 if(!kmp(s, p[i])) { 65 flag = 0; 66 break; 67 } 68 } 69 if(flag) puts(s); 70 else puts("No"); 71 } 72 return 0; 73 }
还可以直接用string的find函数过......
还可以用java过,而且很快......
醉了~
Apple
题意:给四个点,前三个点确定一个外接圆,判断第四个点是否在圆外.
我看的这个题...一开始没注意到精度写了个c++,写完发现精度不够...
java还不会=_=
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************************* 2 > File Name: Main.java 3 > Author: yijiull 4 > Mail: 1147161372@qq.com 5 > Created Time: 2017年09月21日 星期四 19时26分43秒 6 ************************************************************************/ 7 import java.math.BigDecimal; 8 import java.util.*; 9 import java.io.*; 10 public class Main{ 11 public static void main(String[] args){ 12 Scanner cin = new Scanner(new BufferedInputStream(System.in)); 13 BigDecimal x1, x2, y1, y2, x3, y3, x4, y4; 14 int n; 15 n = cin.nextInt(); 16 while(n-- != 0){ 17 x1 = cin.nextBigDecimal(); 18 y1 = cin.nextBigDecimal(); 19 x2 = cin.nextBigDecimal(); 20 y2 = cin.nextBigDecimal(); 21 x3 = cin.nextBigDecimal(); 22 y3 = cin.nextBigDecimal(); 23 x4 = cin.nextBigDecimal(); 24 y4 = cin.nextBigDecimal(); 25 26 BigDecimal v1 =(y1.multiply(y1).add(x1.multiply(x1))).subtract(x3.multiply(x3)).subtract(y3.multiply(y3)); 27 BigDecimal v2 =(y1.multiply(y1).add(x1.multiply(x1))).subtract(x2.multiply(x2)).subtract(y2.multiply(y2)); 28 BigDecimal t1 = x1.subtract(x2); 29 BigDecimal t2 = x1.subtract(x3); 30 BigDecimal t3 = y1.subtract(y3); 31 BigDecimal t4 = y1.subtract(y2); 32 BigDecimal y0 = (v1.multiply(t1).subtract(v2.multiply(t2))).divide(t1.multiply(t3).subtract(t2.multiply(t4))); 33 y0 = y0.divide(BigDecimal.valueOf(2)); 34 35 t1 = y1.subtract(y2); 36 t2 = y1.subtract(y3); 37 t3 = x1.subtract(x3); 38 t4 = x1.subtract(x2); 39 BigDecimal x0 = (v1.multiply(t1).subtract(v2.multiply(t2))).divide(t1.multiply(t3).subtract(t2.multiply(t4))); 40 x0 = x0.divide(BigDecimal.valueOf(2)); 41 42 //System.out.println(x0); 43 //System.out.println(y0); 44 45 BigDecimal r = x0.subtract(x1).multiply(x0.subtract(x1)).add(y0.subtract(y1).multiply(y0.subtract(y1))); 46 BigDecimal d = x0.subtract(x4).multiply(x0.subtract(x4)).add(y0.subtract(y4).multiply(y0.subtract(y4))); 47 48 if(d.compareTo(r) > 0){ 49 System.out.println("Accepted"); 50 } else{ 51 System.out.println("Rejected"); 52 } 53 } 54 } 55 }
算是第一道用java做的题了~
Smallest Minimum Cut
题意:求最小割的最少边数.
建图边权为 w*(m+1)+1, 求出最大流模(m+1)就是答案.最大流除以(m+1)就是原图最大流.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 const int maxv = 210; 5 const int maxe = 1010; 6 7 struct Edge{ 8 int u, v, nex; 9 int flow, cap; 10 Edge(int u=0, int v=0, int nex=0, int flow=0, int cap=0): 11 u(u), v(v), nex(nex), flow(flow), cap(cap){} 12 }e[maxe<<1]; 13 int head[maxv]; 14 int cnt; 15 void init(){ 16 memset(head, -1, sizeof(head)); 17 cnt = 0; 18 } 19 void addEdge(int u, int v, int cap){ 20 e[cnt] = Edge(u, v, head[u], 0, cap); 21 head[u] = cnt++; 22 e[cnt] = Edge(v, u, head[v], 0, 0); 23 head[v] = cnt++; 24 } 25 26 int S, T, N; 27 int vis[maxv], d[maxv], num[maxv], cur[maxv], p[maxv]; 28 29 void bfs(){ 30 queue<int> q; 31 q.push(T); 32 memset(vis, 0, sizeof(vis)); 33 memset(d, -1, sizeof(d)); 34 vis[T] = 1; 35 d[T] = 0; 36 while(!q.empty()){ 37 int u = q.front(); 38 q.pop(); 39 for(int i = head[u]; ~i; i=e[i].nex){ 40 int id = i&(-2); 41 int v = e[id].u; 42 if(!vis[v] && e[id].cap > e[id].flow){ 43 d[v] = d[u] + 1; 44 vis[v] = 1; 45 q.push(v); 46 } 47 } 48 } 49 } 50 int augment(){ 51 int u = T, a = inf; 52 while(u != S){ 53 int id = p[u]; 54 a = min(a, e[id].cap - e[id].flow); 55 u = e[id].u; 56 } 57 u = T; 58 while(u != S){ 59 int id = p[u]; 60 e[id].flow += a; 61 e[id^1].flow -= a; 62 u = e[id].u; 63 } 64 return a; 65 } 66 67 int ISAP(){ 68 bfs(); 69 int flow = 0; 70 memset(num, 0, sizeof(num)); 71 for(int i = 0; i < N; i++){ 72 cur[i] = head[i]; 73 if(~d[i]) num[d[i]]++; 74 } 75 int u = S; 76 while(d[S] < N){ 77 if(u == T){ 78 flow += augment(); 79 u = S; 80 } 81 int ok = 0; 82 for(int i = cur[u]; ~i; i=e[i].nex){ 83 int v = e[i].v; 84 if(d[u] == d[v]+1 && e[i].cap > e[i].flow){ 85 p[v] = i; 86 ok = 1; 87 cur[u] = i; 88 u = v; 89 break; 90 } 91 } 92 if(!ok){ 93 int m = N-1; 94 for(int i = head[u]; ~i; i=e[i].nex){ 95 if(e[i].cap > e[i].flow && ~d[e[i].v]) m = min(m, d[e[i].v]); 96 } 97 if(--num[d[u]] == 0) break; 98 num[d[u] = m+1]++; 99 cur[u] = head[u]; 100 if(u != S) u = e[p[u]].u; 101 } 102 } 103 return flow; 104 } 105 106 int main(){ 107 int n, m, t; 108 //freopen("in.txt", "r", stdin); 109 scanf("%d", &t); 110 while(t--){ 111 init(); 112 scanf("%d %d", &n, &m); 113 scanf("%d %d", &S, &T); 114 S--; T--; 115 for(int i = 0; i < m; i++){ 116 int u, v, cap; 117 scanf("%d %d %d", &u, &v, &cap); 118 u--; v--; 119 addEdge(u, v, cap*(m+1)+1); 120 } 121 122 N = n; 123 int ans = ISAP(); 124 printf("%d\n", ans%(m+1)); 125 } 126 }