今天的模擬賽並不想做什麼總結,也不想寫題解。
進制
讀入p; q; r,求出最小的b(2 ⩽ b ⩽ 16) 使得在b 進制下pb qb = r(pb
爲p 在b 進制下的表示,比如1016 = 1610; 216 816 = 1016)。
若不存在合法的b 輸出0。
1.1 輸入格式
輸入文件爲base:in。
第一行爲數據組數T。
接下來T 行每行三個整數p; q; r,其中p; q 爲十進制數,r 是全由數字
構成的字符串。
1.2 輸出格式
輸出文件爲base:out。
對於每組數據輸出答案。
數據保證有解。
1.3 數據範圍
令b 爲最終答案,t 爲b 進制下r 的大小。
對於所有數據,0 ⩽ p; q; t ⩽ 1018; 1 ⩽ T ⩽ 104。
對於60% 的數據,p; q; t ⩽ 109。
置換
對於給定的長度爲n 的置換p,求最小的k 使得[1; 2 : : : n]pk = [1; 2 : : : n]。
定義置換a b = c 爲,cbi = ai(1 ⩽ i ⩽ n),其中a; b; c 均爲長度爲n
的置換。
由於k 可能很大,請輸出k mod 19184192。
2.1 輸入格式
輸入文件爲perm:in。
第一行一個整數n。
第二行n 個整數表示p。
2.2 輸出格式
輸出文件爲perm:out。
僅一行輸出答案。
2.3 數據範圍
對於所有數據,n ⩽ 105。
對於40% 的數據,n ⩽ 100。
對於60% 的數據,k ⩽ 1018。
24 點
24 點是一個大家熟知的遊戲。
請求解由n 個n 組成的24 點遊戲。
3.1 輸入格式
輸入文件爲card:in。
第一行爲數據組數T。
接下來T 行,每行一個整數表示n。
3.2 輸出格式
輸出文件爲card:out。
對於每組數據,輸出n 1 行:
若無解輸出1。
否則,令A 爲長度2n 1 的數組,初始時81 ⩽ i ⩽ n;Ai = n,表示
初始的n 個n。
對於你輸出的第i 行,格式爲a op b(1 ⩽ a; b < n + i),其中op 爲操
作類型(加+ 減 乘 實數除/),該操作將Aa op Ab 賦值給An+i。
你的輸出需要保證:
• A2n1 = 24
• 每一個Ai 只被至多使用了一次
• A 中任意元素的分子分母的絕對值不大於109。
3.3 數據範圍
對於所有數據
Σ
n ⩽ 105; n ⩽ 200。
對於30% 的數據n ⩽ 6。
對於50% 的數據n ⩽ 15。
對於70% 的數據n ⩽ 30。
反思一下吧:
1.代碼能力還是不夠強。
第一題的高精度勉勉強強過了樣例,滿心以爲是對的,結果爆0,還不停地爆0,怎麼測怎麼錯,說實話到現在也沒發現哪裏錯了。。。。(最近這種情況好多,打完了自信過樣例,隨便做了幾組小數據過了就好了,老是有一點小錯誤)
2.T2也是高精度,(雖然正解是分解質因數來推結論,但是高精度很直白)。。。於是調了巨久也沒有調對,對於高精度取模操作,怎麼調也不對,
3.T3來不及了,題解應該是24以前手推,24以後推規律
4.T4的話,時間上有一點來不及。。最後發現自己求錯東西了,求的是等待時間,我做成求通過時間加上等待時間了,然後因爲本身是求總時間,所以就怎麼也過不去。。。。(等我研究一下再)
題解:
T1:題目中肉眼可見。
題意沒有說清楚,所以明顯的高精度比較穩妥。
下面給出我的代碼和題解代碼,求查錯
我滴垃圾代碼
#include<bits/stdc++.h>
using namespace std;
long long n,m,r;
long long a[110],b[110],c[110],d[220],lenr;
bool zhuan(long long x,long long y,int chu)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(d,0,sizeof(d));
int lena=0;
while (x)
{
a[++lena]=x%chu;
x/=chu;
}
int lenb=0;
while (y)
{
b[++lenb]=y%chu;
y/=chu;
}
for (int i=1; i<=lena; i++)
for (int j=1; j<=lenb; j++)
d[i+j-1]+=a[i]*b[j];
int lend=lena+lenb-1;
long long tmp=0;
for(int i=1;i<=lend;i++) tmp+=d[i],d[i]=tmp%chu,tmp/=chu;
while(tmp) d[++lend]=tmp%chu,tmp/=chu;
if(lend!=lenr) return false;
for (int i=1; i<=lend; i++)
if (d[i]!=c[i]) return false;
return true;
}
int main()
{
int T;
cin>>T;
while (T--)
{
memset(c,0,sizeof(c));
scanf("%lld%lld%lld",&n,&m,&r);
cout<<n<<" "<<m<<" "<<r<<"\n";return 0;
if((n==0||m==0)&&r==0){
printf("2\n");
continue;
}
lenr=0;
while (r)
{
c[++lenr]=r%10;
r/=10;
}
bool p=false;
for (int op=2; op<=16; op++)
{
p=zhuan(n,m,op);
if (p) {printf("%d\n",op);break;}
}
if(!p) printf("0\n");
cout<<p<<"\n";
}
}
跟我一樣方法的ak代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct lll{
int len,p[110];
void read(){
string s;cin>>s;len=s.size();
for(int i=0;i<len;i++) p[len-i]=s[i]-'0';
}
bool operator == (const lll x) const{
if(len!=x.len) return false;
for(int i=1;i<=len;i++) if(p[i]!=x.p[i]) return false;
return true;
}
void turn_it(int bas,ll t){
len=0;
while(t) p[++len]=t%bas,t/=bas;
}
void out(){
for(int i=len;i>=1;i--){
if(p[i]<10) cout<<p[i];
else cout<<p[i]-10+'A';
}
cout<<"\n";
}
}p,q,r,base0;
int base;
ll a,b,T;
lll multy(lll x,lll y){
lll z=base0;
for(int i=1;i<=x.len;i++)
for(int j=1;j<=y.len;j++)
z.p[i+j-1]+=x.p[i]*y.p[j];
z.len=x.len+y.len-1;
long long tmp=0;
for(int i=1;i<=z.len;i++) tmp+=z.p[i],z.p[i]=tmp%base,tmp/=base;
while(tmp) z.p[++z.len]=tmp%base,tmp/=base;
return z;
}
int main(){
base0.len=1;
// freopen("base.in","r",stdin);
// freopen("base.out","w",stdout);
scanf("%lld",&T);
while(T--){
bool flag=false;
scanf("%lld%lld",&a,&b);r.read();
if(r==base0&&(a==0||b==0)){
puts("2");
continue;
}
for(int i=2;i<=16;i++){
base=i,p.turn_it(i,a),q.turn_it(i,b);
if(r==multy(p,q)){
flag=true,printf("%d\n",i);
break;
}
}
if(!flag) puts("0");
}
}
T2
題意概括:就是 (a數組)和p這個數組進行k次題目中說的乘法操作得到c數組(),多少次重新回到
打表出規律
高精就ak
#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;
#define MOD 19184192
struct gaojingdu
{
int a[10005],len;
gaojingdu()
{
memset(a,0,sizeof(a));
len=0;
}
gaojingdu operator +(gaojingdu x) const
{
gaojingdu y;
y.len=max(x.len,len);
for (int i=1;i<=y.len;i++)
{
y.a[i]+=a[i]+x.a[i];
y.a[i+1]+=y.a[i]/10;
y.a[i]%=10;
}
if (y.a[y.len+1]!=0) y.len++;
return y;
}
gaojingdu operator *(gaojingdu x) const
{
gaojingdu t;
t.len=x.len+len-1;
for (int i=1;i<=x.len;i++)
{
for (int j=1;j<=len;j++)
{
t.a[i+j-1]+=x.a[i]*a[j];
t.a[i+j]+=t.a[i+j-1]/10;
t.a[i+j-1]%=10;
}
}
while (t.a[t.len+1]>0)
{
t.len++;
t.a[t.len+1]=t.a[t.len]/10;
t.a[t.len]%=10;
}
return t;
}
gaojingdu operator /(long long x) const
{
gaojingdu t;
t.len=len;
long long y=0;
for (int i=len;i>=1;i--)
{
y=y*10+a[i];
t.a[i]=y/x;
y%=x;
}
while (t.a[t.len]==0) t.len--;
return t;
}
long long operator %(long long x) const
{
gaojingdu t;
t.len=len;
long long y=0;
for (int i=len;i>=1;i--)
{
y=y*10+a[i];
t.a[i]=y/x;
y%=x;
}
return y;
}
bool operator ==(gaojingdu x)
{
if (x.len!=len) return false;
for (int i=1;i<=len;i++)
{
if (a[i]!=x.a[i]) return false;
}
return true;
}
};
long long pow(long long x,int y)
{
long long t=1;
while (y>0)
{
if (y%2==1) t=t*x;
x*=x;
y/=2;
}
return t;
}
gaojingdu zhuan(string s)
{
gaojingdu x;
x.len=s.size();
for (int i=1;i<=x.len;i++)
{
x.a[i]=s[x.len-i]-'0';
}
return x;
}
gaojingdu zhuan(long long x)
{
gaojingdu z;
z.len=0;
while (x>0)
{
z.len++;
z.a[z.len]=x%10;
x/=10;
}
return z;
}
long long zhuan(gaojingdu x)
{
long long y=0;
for (int i=x.len;i>=1;i--)
{
y=y*10+x.a[i];
}
return y;
}
gaojingdu zhuan(long long x,int y)
{
gaojingdu z;
while (x>0)
{
z.len++;
z.a[z.len]=x%y;
x/=y;
}
return z;
}
void write(gaojingdu x)
{
for (int i=x.len;i>=1;i--)
cout<<x.a[i];
}
int n,a[100005],b[100005];
long long gcd(gaojingdu x,long long y)
{
return y==0?zhuan(x):gcd(zhuan(y),x%y);
}
gaojingdu lcm(gaojingdu x,long long y)
{
return x/gcd(x,y)*zhuan(y);
}
int main()
{
// freopen("perm.in","r",stdin);
// freopen("perm.out","w",stdout);
cin>>n;
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
gaojingdu ans=zhuan(1);
for (int i=1;i<=n;i++)
{
if (b[i]==1) continue;
int j=a[i];
long long x=1;
while (j!=i)
{
b[j]=1;
j=a[j];
x=x+1;
}
ans=lcm(ans,x);
}
cout<<ans%MOD;
}
T3
題意概括:大家應該都玩過24點?求n個n能否構成24點。
來不及,就手動推了前五組。。
懶得寫題解了。。。。見代碼。。。
# include <bits/stdc++.h>
using namespace std;
int main()
{
// freopen("card.in","r",stdin);
// freopen("card.out","w",stdout);
int n,tmp, T;
scanf ("%d", &T);
for (int t = 1; t <= T; ++ t){
scanf ("%d", &n);
switch (n) {
case 1:printf("-1\n");break;
case 2:printf("-1\n");break;
case 3:printf("-1\n");break;
case 4:printf("1 * 2\n5 + 3\n6 + 4\n"); break;
case 5:printf("1 * 2\n3 / 6\n4 - 7\n5 * 8\n"); break;
case 6:printf("1 + 2\n3 + 4\n5 - 6\n7 + 8\n10 - 9\n"); break;
case 7:printf("1 + 2\n3 + 8\n9 / 4\n10 + 5\n11 + 6\n12 + 7\n"); break;
case 8:printf("1 + 2\n3 + 9\n4 - 5\n11 * 6\n12 * 7\n13 * 8\n10 + 14\n");break;
case 9:printf("1 + 2\n3 + 10\n4 / 5\n6 / 7\n8 / 9\n11 - 12\n15 - 13\n 16 - 14\n"); break;
case 10:printf("1 + 2\n3 / 4\n5 / 6\n7 / 8\n9 / 10\n11 + 12\n16 + 13\n17 + 14\n18 + 15\n");break;
case 11:printf("1 + 2\n3 / 4\n5 / 6\n7 - 8\n15 * 9\n16 * 10\n17 * 11\n12 + 13\n19 + 14\n20 + 18\n"); break;
case 12:printf("1 + 2\n3 - 4\n5 * 14\n6 * 15\n7 * 16\n8 * 17\n9 * 18\n10 * 19\n11 * 20\n12 * 21\n13 + 22\n"); break;
case 13:printf("1 + 2\n3 / 4\n5 / 6\n7 - 8\n17 * 9\n18 * 10\n19 * 11\n20 * 12\n21 * 13\n22 + 14\n23 - 15\n24 - 16\n"); break;
default: {
printf("1 + 2\n3 + 4\n5 + 6\n7 + 8\n9 + 10\n");
printf("%d + %d\n%d + %d\n%d + %d\n",n+1,n+2,n+3,n+4,n+5,n+6);
printf("%d / 11\n%d / 12\n",n+7,n+8);
printf("%d * %d\n",n+9,n+10);
printf("13 - 14\n");
tmp=n-14;
int i;
for(i=0;i<tmp;i++) printf("%d * %d\n",n+12+i,15+i);
printf("%d + %d\n",n+11,n+12+tmp);
}
break;
}
}
return 0;
}
T4
3.飛揚的小鳥
(bird.cpp\c\pas)
【問題描述】
Flappy Bird是一款風靡一時的休閒手機遊戲。玩家需要不斷控制點擊手機屏幕的頻率來調節小鳥的飛行高度,讓小鳥順利通過畫面右方的管道縫隙。如果小鳥一不小心撞到了水管或者掉在地上的話,便宣告失敗。
現在小鳥們遇到了一個難題,他們遇到了一堵巨大的牆,牆上僅有m個洞供他們通過,由於小鳥們的體型不同且牆上洞的形狀也不同,所以每種體型的鳥通過每個洞的時間都不同,鳥的體型共有n種,第i種體型的鳥通過第j個洞需要的時間記爲T(i,j),且一個洞必須前一隻鳥通過之後後一隻鳥才能開始通過。
從時刻0開始,鳥開始通過,而每一隻鳥的等待時間爲從時刻0到自己已經通過洞的時間。現在知道了第i種體型的鳥有pi只,請求出使所有鳥都通過牆的最少的等待時間之和。
【輸入格式】
第1行包含兩個正整數n和m,表示鳥的體型的種數和牆洞的數量。
第2行包含n個正整數,其中第i個數爲pi,表示點第i種體型的鳥的只數。
接下來有n行,每行包含m個非負整數,這n行中的第i行的第j個數爲t(i,j),表示第i種體型的鳥通過第j個牆洞所需的時間。輸入文件中每行相鄰的兩個數之間均由一個空格隔開,行末均沒有多餘空格。
【輸出格式】
輸出僅一行包含一個整數,爲總等待時間的最小值。
題意概括:
n種鳥,m個洞,不同種鳥過不同種洞有不同時間,求最少等待時間(後面等待的鳥等待的時間)。
這個題是今天最有含金量的題了,可惜沒題解??
乍一眼看可能個排隊接水的進階版很像,可惜肯定不是貪心,DP的話額、
DP個屁啊,
尼瑪我@#¥%&YUI&%$#$%U
網絡流
考慮如果一隻種類爲i的鳥倒數第一個通過洞j,那麼對於總代價的貢獻爲T(i,j),倒數第k則貢獻爲T(i,j)*k。
根據這個,我們就可以建圖了。
源點向每一種鳥連邊,對於第i種鳥,連一條流量爲p[i]費用爲0的邊。
對於每一個洞,我們拆成個洞,也就是總共拆成了的洞,每個洞向匯點連一條流量爲1費用爲0的邊。
然後每一種鳥向每一個洞都連一條邊。第i種鳥,向第(k-1)*m+j個洞(這裏指的是拆後的洞)連一條流量爲1,費用爲的
邊,這條邊若滿流則表示的意義爲一隻種類爲i的鳥倒數第k個通過了洞,且該洞爲第j個洞(這裏指原來的洞)。
然而點數最大爲40+100800,邊數最大爲40+10080+4010080,直接做顯然會超時。
注意到若第(k-1)m+j個洞向匯點的邊沒有滿流,則第km+j個洞顯然也不會滿流(即還用不到),以可以動態加邊。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
#define MAXD 100010
#define MAXN 50
#define MAXM 110
using namespace std;
int n, m, p[MAXN], t[MAXN][MAXM], cnt;
int S, T, dis[MAXD], frm[MAXD], rk[MAXD], ansflow, anscost;
struct info{int v, c, w; unsigned r;};
vector <info> a[MAXD];
template <typename T> void chkmin(T &x, T y){x = min(x, y);}
template <typename T> void chkmax(T &x, T y){x = max(x, y);}
template <typename T> void read(T &x){
x = 0; int f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
void add(int u, int v, int c, int w){
a[u].push_back((info){v, c, w, (unsigned)a[v].size()});
a[v].push_back((info){u, 0, -w, (unsigned)a[u].size() - 1});
}
int spfa(){
static int q[MAXD * 200], inq[MAXD], l = 0, r = 0;
for (int i = 0; i <= r; ++i)
dis[q[i]] = INF;
q[l = r = 0] = S, dis[S] = 0, inq[S] = 1;
while (l <= r) {
int pos = q[l++];
for (unsigned i = 0, si = a[pos].size(); i < si; ++i){
int to = a[pos][i].v, wth = a[pos][i].w, cap = a[pos][i].c;
if (cap && dis[to] > dis[pos] + wth) {
dis[to] = dis[pos] + wth;
frm[to] = pos, rk[to] = i;
if (!inq[to]) q[++r] = to, inq[to] = 1;
}
}
inq[pos] = 0;
}
return (dis[T] != INF);
}
void flow(){
int pos = T, f = INF;
while (pos != S) {
info tmp = a[frm[pos]][rk[pos]];
chkmin(f, tmp.c);
pos = frm[pos];
}
ansflow += f, anscost += f * dis[T], pos = T;
while (pos != S) {
info &tmp = a[frm[pos]][rk[pos]];
tmp.c -= f;
a[pos][tmp.r].c += f;
pos = frm[pos];
}
}
void addedg(int dep){
for (int i = 1; i <= m; ++i){
int d = ++cnt;
add(d, T, 1, 0);
for (int j = 1; j <= n; ++j)
add(j, d, 1, dep * t[j][i]);
}
}
int main(){
freopen("bird.in", "r", stdin);
freopen("bird.out", "w", stdout);
memset(dis, INF, sizeof(dis));
read(n), read(m);
for (int i = 1; i <= n; ++i)
read(p[i]);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
read(t[i][j]);
S = 0, T = n + 1, cnt = n + 1;
for (int i = 1; i <= n; ++i)
add(S, i, p[i], 0);
int dep = 1;
addedg(dep);
while (spfa()){
flow();
++dep;
addedg(dep);
}
printf("%d\n", anscost);
return 0;
}
今天估分 100+50(高精度寫掛了,交了暴力,不知道爲啥暴力也掛了)+10+0
實際:
0
憑實力爆的0,絕對沒有結果,就是代碼能力不夠,沒有什麼其他原因,如何證明這不是自己的實力?那就是明天好好打,該拿的分絕對不能放。